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/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/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java b/api/src/com/cloud/agent/api/storage/CopyTemplateToPrimaryStorageAnswer.java similarity index 95% rename from engine/storage/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/storage/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/core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java b/api/src/com/cloud/agent/api/storage/PasswordAuth.java old mode 100755 new mode 100644 similarity index 69% rename from core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java rename to api/src/com/cloud/agent/api/storage/PasswordAuth.java index 949af010423..f03c584c660 --- a/core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java +++ b/api/src/com/cloud/agent/api/storage/PasswordAuth.java @@ -16,23 +16,24 @@ // under the License. package com.cloud.agent.api.storage; -public class DeleteVolumeCommand extends ssCommand { - private String volumePath; +/** + * Password authentication + */ +public class PasswordAuth { - public DeleteVolumeCommand() { - } + String userName; + String password; + public PasswordAuth() { - public DeleteVolumeCommand(String secUrl, String volumePath) { - this.setSecUrl(secUrl); - this.volumePath = volumePath; } - - @Override - public boolean executeInSequence() { - return true; + public PasswordAuth(String user, String password) { + this.userName = user; + this.password = password; + } + public String getUserName() { + return userName; + } + public String getPassword() { + return password; } - - public String getVolumePath() { - return volumePath; - } } 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/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/ImageDataStoreProvider.java b/api/src/com/cloud/agent/api/to/DataStoreTO.java similarity index 85% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageDataStoreProvider.java rename to api/src/com/cloud/agent/api/to/DataStoreTO.java index 1fb987e81cd..9014f8e2b81 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageDataStoreProvider.java +++ b/api/src/com/cloud/agent/api/to/DataStoreTO.java @@ -16,9 +16,11 @@ * 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 ImageDataStoreProvider extends DataStoreProvider { - +public interface DataStoreTO { + public DataStoreRole getRole(); } diff --git a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java b/api/src/com/cloud/agent/api/to/DataTO.java similarity index 79% rename from engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java rename to api/src/com/cloud/agent/api/to/DataTO.java index 7a476367d37..21e802fde1f 100644 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java +++ b/api/src/com/cloud/agent/api/to/DataTO.java @@ -16,9 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.motion; +package com.cloud.agent.api.to; -import org.apache.cloudstack.storage.motion.DataMotionStrategy; +public interface DataTO { + public DataObjectType getObjectType(); + public DataStoreTO getDataStore(); + /** + * @return + */ + String getPath(); -public interface ImageMotionStrategy extends DataMotionStrategy { + long getId(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java b/api/src/com/cloud/agent/api/to/DiskTO.java similarity index 51% rename from engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java rename to api/src/com/cloud/agent/api/to/DiskTO.java index ccb6b483253..7b32f006606 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java +++ b/api/src/com/cloud/agent/api/to/DiskTO.java @@ -16,23 +16,45 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.datastore.db; +package com.cloud.agent.api.to; -import org.springframework.stereotype.Component; +import com.cloud.storage.Volume; -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(); +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; } -} \ No newline at end of file + 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/FirewallRuleTO.java b/api/src/com/cloud/agent/api/to/FirewallRuleTO.java index de7307669cb..c6ee9f24a11 100644 --- a/api/src/com/cloud/agent/api/to/FirewallRuleTO.java +++ b/api/src/com/cloud/agent/api/to/FirewallRuleTO.java @@ -52,6 +52,9 @@ public class FirewallRuleTO implements InternalIdentity { private Integer icmpType; private Integer icmpCode; private FirewallRule.TrafficType trafficType; + private String guestCidr; + private boolean defaultEgressPolicy; + private FirewallRule.FirewallRuleType type; protected FirewallRuleTO() { } @@ -109,9 +112,12 @@ public class FirewallRuleTO implements InternalIdentity { this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), revokeState, alreadyAdded, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode()); } - public FirewallRuleTO(FirewallRule rule, String guestVlanTag, FirewallRule.TrafficType trafficType) { + public FirewallRuleTO(FirewallRule rule, String guestVlanTag, FirewallRule.TrafficType trafficType, String guestCidr, boolean defaultEgressPolicy, FirewallRule.FirewallRuleType type) { this(rule.getId(), guestVlanTag, null, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(), rule.getSourceCidrList(), rule.getIcmpType(), rule.getIcmpCode()); this.trafficType = trafficType; + this.defaultEgressPolicy = defaultEgressPolicy; + this.guestCidr = guestCidr; + this.type = type; } public FirewallRule.TrafficType getTrafficType(){ @@ -169,4 +175,15 @@ public class FirewallRuleTO implements InternalIdentity { return purpose; } + public boolean isDefaultEgressPolicy() { + return defaultEgressPolicy; + } + + public String getGuestCidr() { + return guestCidr; + } + + public FirewallRule.FirewallRuleType getType() { + return type; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java b/api/src/com/cloud/agent/api/to/NfsTO.java similarity index 57% rename from engine/storage/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java rename to api/src/com/cloud/agent/api/to/NfsTO.java index 96fb6bb2401..5490fd1e588 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java +++ b/api/src/com/cloud/agent/api/to/NfsTO.java @@ -14,31 +14,47 @@ // 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; +package com.cloud.agent.api.to; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; +import com.cloud.storage.DataStoreRole; + +public final class NfsTO implements DataStoreTO { + + private String _url; + private DataStoreRole _role; + + public NfsTO() { + + super(); -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 NfsTO(String url, DataStoreRole role) { + + super(); + + this._url = url; + this._role = role; + } - - public String getServer() { - return this.server; + + public String getUrl() { + return _url; } - - public void setPath(String path) { - this.path = path; + + public void setUrl(String _url) { + this._url = _url; } - - public String getPath() { - return this.path; + + @Override + public DataStoreRole getRole() { + return _role; } + + public void setRole(DataStoreRole _role) { + this._role = _role; + } + + + } diff --git a/api/src/com/cloud/agent/api/to/S3TO.java b/api/src/com/cloud/agent/api/to/S3TO.java index d556cb6d05d..8a2f09dc5ab 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; @@ -33,6 +34,7 @@ public final class S3TO implements S3Utils.ClientOptions { private Integer maxErrorRetry; private Integer socketTimeout; private Date created; + private boolean enableRRS; public S3TO() { @@ -44,7 +46,7 @@ public final class S3TO implements S3Utils.ClientOptions { 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(); @@ -59,6 +61,7 @@ public final class S3TO implements S3Utils.ClientOptions { this.maxErrorRetry = maxErrorRetry; this.socketTimeout = socketTimeout; this.created = created; + this.enableRRS = enableRRS; } @@ -128,6 +131,10 @@ public final class S3TO implements S3Utils.ClientOptions { return false; } + if (enableRRS != thatS3TO.enableRRS) { + return false; + } + return true; } @@ -249,4 +256,20 @@ public final class S3TO implements S3Utils.ClientOptions { this.created = created; } + @Override + public DataStoreRole getRole() { + return DataStoreRole.Image; + } + + + + public boolean getEnableRRS() { + return enableRRS; + } + + public void setEnableRRS(boolean enableRRS) { + this.enableRRS = enableRRS; + } + + } 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/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java index 46ee01bc8a3..e6240ffda10 100644 --- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -58,7 +58,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) { @@ -215,11 +215,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/agent/api/to/VolumeTO.java b/api/src/com/cloud/agent/api/to/VolumeTO.java index 4cbe82b357b..cc0e8182390 100644 --- a/api/src/com/cloud/agent/api/to/VolumeTO.java +++ b/api/src/com/cloud/agent/api/to/VolumeTO.java @@ -37,6 +37,10 @@ public class VolumeTO implements InternalIdentity { private long deviceId; private String chainInfo; private String guestOsType; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; public VolumeTO(long id, Volume.Type type, StoragePoolType poolType, String poolUuid, String name, String mountPoint, String path, long size, String chainInfo) { this.id = id; @@ -133,4 +137,37 @@ public class VolumeTO implements InternalIdentity { public String toString() { return new StringBuilder("Vol[").append(id).append("|").append(type).append("|").append(path).append("|").append(size).append("]").toString(); } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + } diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 05307eb47aa..ea39d835eb7 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -274,4 +274,6 @@ public interface NetworkModel { Networks.IsolationType[] listNetworkIsolationMethods(); Nic getNicInNetworkIncludingRemoved(long vmId, long networkId); + + boolean getExecuteInSeqNtwkElmtCmd(); } \ No newline at end of file diff --git a/api/src/com/cloud/offering/DiskOffering.java b/api/src/com/cloud/offering/DiskOffering.java index dd77c70abd9..ae4528cc81a 100644 --- a/api/src/com/cloud/offering/DiskOffering.java +++ b/api/src/com/cloud/offering/DiskOffering.java @@ -52,4 +52,20 @@ public interface DiskOffering extends InfrastructureEntity, Identity, InternalId boolean isCustomized(); void setDiskSize(long diskSize); + + void setBytesReadRate(Long bytesReadRate); + + Long getBytesReadRate(); + + void setBytesWriteRate(Long bytesWriteRate); + + Long getBytesWriteRate(); + + void setIopsReadRate(Long iopsReadRate); + + Long getIopsReadRate(); + + void setIopsWriteRate(Long iopsWriteRate); + + Long getIopsWriteRate(); } diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 5f522ebff6a..43312db0d18 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -127,5 +127,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, boolean getInternalLb(); boolean getPublicLb(); + boolean getEgressDefaultPolicy(); } diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index ca8a6894057..0a69fa54928 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -124,15 +124,6 @@ public interface ManagementService { */ Pair, Integer> searchForServers(ListHostsCmd cmd); - /** - * Creates a new template - * - * @param cmd - * @return updated template - */ - VirtualMachineTemplate updateTemplate(UpdateIsoCmd cmd); - - VirtualMachineTemplate updateTemplate(UpdateTemplateCmd cmd); @@ -223,28 +214,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 @@ -271,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 * 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/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java b/api/src/com/cloud/storage/GuestOSHypervisor.java similarity index 77% rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java rename to api/src/com/cloud/storage/GuestOSHypervisor.java index b248758bc12..f022722af04 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java +++ b/api/src/com/cloud/storage/GuestOSHypervisor.java @@ -14,3 +14,15 @@ // 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/core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java b/api/src/com/cloud/storage/ImageStore.java similarity index 62% rename from core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java rename to api/src/com/cloud/storage/ImageStore.java index 69f465c6b16..d2a72a21fa6 100644 --- a/core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java +++ b/api/src/com/cloud/storage/ImageStore.java @@ -14,27 +14,34 @@ // 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 com.cloud.storage; + +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +public interface ImageStore extends Identity, InternalIdentity { -public class DeleteTemplateCommand extends ssCommand { - private String templatePath; + /** + * @return name of the object store. + */ + String getName(); + + /** + * @return availability zone. + */ + Long getDataCenterId(); - public DeleteTemplateCommand() { - } + /** + * @return object store provider name + */ + String getProviderName(); - public DeleteTemplateCommand(String secUrl, String templatePath) { - this.setSecUrl(secUrl); - this.templatePath = templatePath; - } - @Override - public boolean executeInSequence() { - return true; - } - - public String getTemplatePath() { - return templatePath; - } + /** + * + * @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/com/cloud/storage/Snapshot.java b/api/src/com/cloud/storage/Snapshot.java index 842843e3864..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 } @@ -86,8 +91,6 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, long getVolumeId(); - String getPath(); - String getName(); Date getCreated(); diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/Storage.java index c130fe222bf..16ef0192e32 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 { @@ -97,8 +98,8 @@ public class Storage { Iscsi(true), // for e.g., ZFS Comstar ISO(false), // for iso image LVM(false), // XenServer local LVM SR - CLVM(true), - RBD(true), + CLVM(true), + RBD(true), // http://libvirt.org/storage.html#StorageBackendRBD SharedMountPoint(true), VMFS(true), // VMware VMFS storage PreSetup(true), // for XenServer, Storage Pool is set up by customers. 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/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index 63c5023ee91..869b2960e1c 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -18,12 +18,17 @@ 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.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; 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; @@ -43,6 +48,8 @@ public interface StorageService{ */ StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException; + + ImageStore createCacheStore(CreateCacheStoreCmd cmd); /** * Delete the storage pool @@ -82,4 +89,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/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/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 4903594f0af..f5ed4e267b6 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); @@ -152,7 +153,7 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba Date getCreated(); - long getDiskOfferingId(); + Long getDiskOfferingId(); String getChainInfo(); @@ -173,4 +174,5 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba * @param reserv */ void setReservationId(String reserv); + Storage.ImageFormat getFormat(); } diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 7e5ebe21200..95f962df374 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 @@ -58,7 +61,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 @@ -75,5 +78,24 @@ public interface VolumeApiService { Volume detachVolumeFromVM(DetachVolumeCmd cmmd); + 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 + * + */ + String extractVolume(ExtractVolumeCmd cmd); } 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/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 86% rename from api/src/com/cloud/template/TemplateService.java rename to api/src/com/cloud/template/TemplateApiService.java index 7e831fb0055..26f381914c9 100755 --- a/api/src/com/cloud/template/TemplateService.java +++ b/api/src/com/cloud/template/TemplateApiService.java @@ -24,19 +24,22 @@ 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; import com.cloud.exception.StorageUnavailableException; import com.cloud.user.Account; +import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; -public interface TemplateService { +public interface TemplateApiService { VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException; @@ -72,29 +75,32 @@ public interface TemplateService { * * @param cmd * - the command specifying the mode and id of the ISO - * @return extractId. + * @return extractUrl extract url. */ - Long 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 */ - Long extract(ExtractTemplateCmd cmd) throws InternalErrorException; + String extract(ExtractTemplateCmd cmd) throws InternalErrorException; VirtualMachineTemplate getTemplate(long templateId); 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/com/cloud/template/VirtualMachineTemplate.java b/api/src/com/cloud/template/VirtualMachineTemplate.java index cedc793c197..114785a28be 100755 --- a/api/src/com/cloud/template/VirtualMachineTemplate.java +++ b/api/src/com/cloud/template/VirtualMachineTemplate.java @@ -92,4 +92,6 @@ public interface VirtualMachineTemplate extends ControlledEntity, Identity, Inte String getTemplateTag(); Map getDetails(); + + Boolean isDynamicallyScalable(); } diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java index e3a3386d1e5..3d4c9e730f4 100644 --- a/api/src/com/cloud/vm/DiskProfile.java +++ b/api/src/com/cloud/vm/DiskProfile.java @@ -35,6 +35,10 @@ public class DiskProfile { private Long templateId; private long volumeId; private String path; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; private HypervisorType hyperType; @@ -154,4 +158,36 @@ public class DiskProfile { public void setSize(long size) { this.size = size; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index fe0ea764aae..ce2d90e5863 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -161,6 +161,8 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I } } + public static final String IsDynamicScalingEnabled = "enable.dynamic.scaling"; + public enum Event { StartRequested, StopRequested, diff --git a/api/src/com/cloud/vm/VirtualMachineProfile.java b/api/src/com/cloud/vm/VirtualMachineProfile.java index 8460e10cd45..b138aeb0cca 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; @@ -133,11 +135,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(); @@ -147,7 +149,7 @@ public interface VirtualMachineProfile { void addNic(NicProfile nic); - void addDisk(VolumeTO disk); + void addDisk(DiskTO disk); VirtualMachine.Type getType(); diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index ab1402ccde9..8ac7c3fc064 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -31,6 +31,8 @@ public class ApiConstants { public static final String BOOTABLE = "bootable"; public static final String BIND_DN = "binddn"; public static final String BIND_PASSWORD = "bindpass"; + public static final String BYTES_READ_RATE = "bytesreadrate"; + public static final String BYTES_WRITE_RATE = "byteswriterate"; public static final String CATEGORY = "category"; public static final String CERTIFICATE = "certificate"; public static final String PRIVATE_KEY = "privatekey"; @@ -104,6 +106,8 @@ public class ApiConstants { public static final String INTERNAL_DNS1 = "internaldns1"; public static final String INTERNAL_DNS2 = "internaldns2"; public static final String INTERVAL_TYPE = "intervaltype"; + public static final String IOPS_READ_RATE = "iopsreadrate"; + public static final String IOPS_WRITE_RATE = "iopswriterate"; public static final String IP_ADDRESS = "ipaddress"; public static final String IP6_ADDRESS = "ip6address"; public static final String IP_ADDRESS_ID = "ipaddressid"; @@ -117,6 +121,7 @@ public class ApiConstants { public static final String IS_PORTABLE = "isportable"; public static final String IS_PUBLIC = "ispublic"; public static final String IS_PERSISTENT = "ispersistent"; + public static final String EGRESS_DEFAULT_POLICY = "egressdefaultpolicy"; public static final String IS_READY = "isready"; public static final String IS_RECURSIVE = "isrecursive"; public static final String ISO_FILTER = "isofilter"; @@ -241,8 +246,7 @@ public class ApiConstants { public static final String IS_VOLATILE = "isvolatile"; public static final String VOLUME_ID = "volumeid"; public static final String ZONE_ID = "zoneid"; - public static final String ZONE_NAME = "zonename"; - public static final String ZONE_TYPE = "zonetype"; + public static final String ZONE_NAME = "zonename"; public static final String NETWORK_TYPE = "networktype"; public static final String PAGE = "page"; public static final String PAGE_SIZE = "pagesize"; @@ -506,6 +510,7 @@ public class ApiConstants { public static final String DEPLOYMENT_PLANNER = "deploymentplanner"; public static final String ACL_ID = "aclid"; public static final String NUMBER = "number"; + public static final String IS_DYNAMICALLY_SCALABLE = "isdynamicallyscalable"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index 4019db02437..1f86c2333f2 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -68,8 +68,8 @@ 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.template.TemplateService; +import com.cloud.storage.snapshot.SnapshotApiService; +import com.cloud.template.TemplateApiService; import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.user.DomainService; @@ -115,9 +115,9 @@ 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 SnapshotApiService _snapshotService; @Inject public VpcVirtualNetworkApplianceService _routerService; @Inject public ResponseGenerator _responseGenerator; @Inject public EntityManager _entityMgr; diff --git a/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java b/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java index 75a722ecd33..74585771017 100644 --- a/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java @@ -55,6 +55,9 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd { @Parameter(name=ApiConstants.SORT_KEY, type=CommandType.INTEGER, description="sort key of the template, integer") private Integer sortKey; + @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if template/ISO contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory") + private Boolean isDynamicallyScalable; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -90,4 +93,8 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd { public Integer getSortKey() { return sortKey; } + + public Boolean isDynamicallyScalable() { + return isDynamicallyScalable; + } } diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 386b16c72fb..dca26fb5516 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -51,6 +51,7 @@ import org.apache.cloudstack.api.response.HostForMigrationResponse; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse; import org.apache.cloudstack.api.response.IPAddressResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse; import org.apache.cloudstack.api.response.IpForwardingRuleResponse; @@ -172,6 +173,7 @@ import com.cloud.projects.ProjectInvitation; import com.cloud.region.ha.GlobalLoadBalancerRule; import com.cloud.server.ResourceTag; import com.cloud.storage.GuestOS; +import com.cloud.storage.ImageStore; import com.cloud.storage.S3; import com.cloud.storage.Snapshot; import com.cloud.storage.StoragePool; @@ -277,7 +279,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); @@ -293,13 +295,17 @@ 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); + + ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url); EventResponse createEventResponse(Event event); //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); @@ -319,13 +325,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); @@ -358,6 +364,8 @@ public interface ResponseGenerator { RegionResponse createRegionResponse(Region region); + ImageStoreResponse createImageStoreResponse(ImageStore os); + /** * @param resourceTag * @param keyValueOnly TODO 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 d876baeddea..e29e7944030 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,8 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.admin.host; -import java.util.List; - import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -26,14 +24,15 @@ 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.command.admin.storage.AddImageStoreCmd; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.ZoneResponse; 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"; @@ -49,6 +48,8 @@ public class AddSecondaryStorageCmd extends BaseCmd { description="the Zone ID for the secondary storage") private Long zoneId; + + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -61,6 +62,7 @@ public class AddSecondaryStorageCmd extends BaseCmd { return zoneId; } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -77,17 +79,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(getUrl()); + cmd.setZoneId(getZoneId()); + cmd.setProviderName("NFS"); + + try{ + ImageStore result = _storageService.discoverImageStore(cmd); + ImageStoreResponse storeResponse = null; + if (result != null ) { + storeResponse = _responseGenerator.createImageStoreResponse(result); + storeResponse.setResponseName(getCommandName()); + storeResponse.setObjectName("secondarystorage"); + setResponseObject(storeResponse); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage"); } diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java index 7822f4a363b..7db85f3bbe4 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java @@ -71,13 +71,12 @@ public class FindHostsForMigrationCmd extends BaseListCmd { public void execute() { ListResponse response = null; Pair,Integer> result; - List hostsWithCapacity = new ArrayList(); Map hostsRequiringStorageMotion; Ternary,Integer>, List, Map> hostsForMigration = _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal()); result = hostsForMigration.first(); - hostsWithCapacity = hostsForMigration.second(); + List hostsWithCapacity = hostsForMigration.second(); hostsRequiringStorageMotion = hostsForMigration.third(); response = new ListResponse(); diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java index cf1f5be7cc7..bec6edf966c 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java @@ -172,11 +172,10 @@ public class ListHostsCmd extends BaseListCmd { response = _queryService.searchForServers(this); } else { Pair,Integer> result; - List hostsWithCapacity = new ArrayList(); Ternary,Integer>, List, Map> hostsForMigration = _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal()); result = hostsForMigration.first(); - hostsWithCapacity = hostsForMigration.second(); + List hostsWithCapacity = hostsForMigration.second(); response = new ListResponse(); List hostResponses = new ArrayList(); diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java index fd1ad570251..106d561ac23 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java @@ -77,9 +77,6 @@ public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd @Parameter(name=ApiConstants.FOR_VPC, type=CommandType.BOOLEAN, description="if true is passed for this parameter, list only VPC Internal LB VMs") private Boolean forVpc; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -125,9 +122,6 @@ public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd return Role.INTERNAL_LB_VM.toString(); } - public String getZoneType() { - return zoneType; - } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java b/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java index 7f3180001d2..d2163b810d9 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java @@ -17,6 +17,9 @@ package org.apache.cloudstack.api.command.admin.ldap; +import java.util.ArrayList; +import java.util.List; + import javax.naming.NamingException; import org.apache.log4j.Logger; @@ -27,6 +30,7 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.LDAPConfigResponse; +import org.apache.cloudstack.api.response.ListResponse; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -91,7 +95,7 @@ public class LDAPConfigCmd extends BaseCmd { } public void setBindDN(String bdn) { - this.bindDN=bdn; + bindDN=bdn; } public String getQueryFilter() { @@ -159,9 +163,16 @@ public class LDAPConfigCmd extends BaseCmd { if (getListAll()){ // return the existing conf LDAPConfigCmd cmd = _configService.listLDAPConfig(this); - LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN()); - lr.setResponseName(getCommandName()); - this.setResponseObject(lr); + ListResponse response = new ListResponse(); + List responses = new ArrayList(); + + if(!cmd.getHostname().equals("")) { + responses.add(_responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN())); + } + + response.setResponses(responses); + response.setResponseName(getCommandName()); + setResponseObject(response); } else if (getHostname()==null || getSearchBase() == null || getQueryFilter() == null) { throw new InvalidParameterValueException("You need to provide hostname, searchbase and queryfilter to configure your LDAP server"); @@ -171,7 +182,7 @@ public class LDAPConfigCmd extends BaseCmd { if (result){ LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(getHostname(), getPort(), getUseSSL(), getQueryFilter(), getSearchBase(), getBindDN()); lr.setResponseName(getCommandName()); - this.setResponseObject(lr); + setResponseObject(lr); } } } diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index 621e6e53d0e..48aa790249e 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -100,6 +100,9 @@ public class CreateNetworkOfferingCmd extends BaseCmd { " Supported keys are internallbprovider/publiclbprovider with service provider as a value") protected Map details; + @Parameter(name=ApiConstants.EGRESS_DEFAULT_POLICY, type=CommandType.BOOLEAN, description="true if default guest network egress policy is allow; false if default egress policy is deny") + private Boolean egressDefaultPolicy; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -163,6 +166,13 @@ public class CreateNetworkOfferingCmd extends BaseCmd { return isPersistent == null ? false : isPersistent; } + public Boolean getEgressDefaultPolicy() { + if (egressDefaultPolicy == null) { + return true; + } + return egressDefaultPolicy; + } + public Map> getServiceProviders() { Map> serviceProviderMap = null; if (serviceProviderList != null && !serviceProviderList.isEmpty()) { diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java index 1e178f1869f..9c86dcc9cfe 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java @@ -63,6 +63,18 @@ public class CreateDiskOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.STORAGE_TYPE, type=CommandType.STRING, description="the storage type of the disk offering. Values are local and shared.") private String storageType = ServiceOffering.StorageType.shared.toString(); + @Parameter(name=ApiConstants.BYTES_READ_RATE, type=CommandType.LONG, required=false, description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @Parameter(name=ApiConstants.BYTES_WRITE_RATE, type=CommandType.LONG, required=false, description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @Parameter(name=ApiConstants.IOPS_READ_RATE, type=CommandType.LONG, required=false, description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @Parameter(name=ApiConstants.IOPS_WRITE_RATE, type=CommandType.LONG, required=false, description="io requests write rate of the disk offering") + private Long iopsWriteRate; + @Parameter(name=ApiConstants.DISPLAY_OFFERING, type=CommandType.BOOLEAN, description="an optional field, whether to display the offering to the end user or not.") private Boolean displayOffering; @@ -94,6 +106,22 @@ public class CreateDiskOfferingCmd extends BaseCmd { return domainId; } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + public String getStorageType() { return storageType; } diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java index fcbfa4adabc..f90e0593ecd 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java @@ -94,6 +94,18 @@ public class CreateServiceOfferingCmd extends BaseCmd { @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters") private Map details; + @Parameter(name=ApiConstants.BYTES_READ_RATE, type=CommandType.LONG, required=false, description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @Parameter(name=ApiConstants.BYTES_WRITE_RATE, type=CommandType.LONG, required=false, description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @Parameter(name=ApiConstants.IOPS_READ_RATE, type=CommandType.LONG, required=false, description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @Parameter(name=ApiConstants.IOPS_WRITE_RATE, type=CommandType.LONG, required=false, description="io requests write rate of the disk offering") + private Long iopsWriteRate; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -172,6 +184,22 @@ public class CreateServiceOfferingCmd extends BaseCmd { return params; } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java b/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java index 75bcce00acf..1f77c2c5164 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java @@ -81,9 +81,8 @@ public class ListPortableIpRangesCmd extends BaseListCmd { public void execute(){ ListResponse response = new ListResponse(); List responses = new ArrayList(); - List portableIpRanges = new ArrayList(); - portableIpRanges = _configService.listPortableIpRanges(this); + List portableIpRanges = _configService.listPortableIpRanges(this); if (portableIpRanges != null && !portableIpRanges.isEmpty()) { for (PortableIpRange range : portableIpRanges) { PortableIpRangeResponse rangeResponse = _responseGenerator.createPortableIPRangeResponse(range); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java index ce5a1306175..7433c1b6ea7 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java @@ -66,9 +66,6 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { description="the Zone ID of the router") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType=NetworkResponse.class, description="list by network id") private Long networkId; @@ -108,10 +105,6 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public Long getNetworkId() { return networkId; } 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..1e383c9647b --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.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 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; +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, 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"; + + ///////////////////////////////////////////////////// + //////////////// 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; + + @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.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. Example: details[0].key=accesskey&details[0].value=s389ddssaa&details[1].key=secretkey&details[1].value=8dshfsss") + private Map details; + + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public String getUrl() { + return url; + } + + public String getName() { + return name; + } + + public Long getZoneId() { + return zoneId; + } + + public Map getDetails() { + Map detailsMap = null; + if (details != null && !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() { + 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; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute(){ + try{ + ImageStore result = _storageService.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/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/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/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..20ddc8b6fec --- /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, since = "4.2.0") +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/api/src/org/apache/cloudstack/api/command/admin/storage/ListCacheStoresCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListCacheStoresCmd.java new file mode 100644 index 00000000000..3909e8ec55c --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListCacheStoresCmd.java @@ -0,0 +1,104 @@ +// 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.ImageStoreResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; + +@APICommand(name = "listCacheStores", description="Lists cache stores.", responseObject=ImageStoreResponse.class, since = "4.2.0") +public class ListCacheStoresCmd extends BaseListCmd { + public static final Logger s_logger = Logger.getLogger(ListCacheStoresCmd.class.getName()); + + private static final String s_name = "listcachestoreresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the cache store") + private String storeName; + + @Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, description="the cache store protocol") + private String protocol; + + @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING, description="the cache store provider") + private String provider; + + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class, + description="the Zone ID for the cache store") + private Long zoneId; + + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = ImageStoreResponse.class, + description="the ID of the cache store") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + + public Long getZoneId() { + return zoneId; + } + + public String getStoreName() { + return storeName; + } + + public String getProtocol() { + return protocol; + } + + public Long getId() { + return id; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + + + @Override + public String getCommandName() { + return s_name; + } + + + @Override + public void execute(){ + ListResponse response = _queryService.searchForCacheStores(this); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} 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..7063e6c6bda --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java @@ -0,0 +1,104 @@ +// 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.ImageStoreResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; + +@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()); + + 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.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 = ImageStoreResponse.class, + description="the ID of the storage pool") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + + public Long getZoneId() { + return zoneId; + } + + public String getStoreName() { + return storeName; + } + + public String getProtocol() { + return protocol; + } + + public Long getId() { + return id; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = 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/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/storage/ListStoragePoolsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java index 367d1e636bd..f37a282eb86 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java @@ -65,6 +65,10 @@ public class ListStoragePoolsCmd extends BaseListCmd { description="the ID of the storage pool") private Long id; + @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING, entityType = StoragePoolResponse.class, + description="the ID of the storage pool") + private String scope; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -116,4 +120,8 @@ public class ListStoragePoolsCmd extends BaseListCmd { response.setResponseName(getCommandName()); this.setResponseObject(response); } + + public String getScope() { + return scope; + } } 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 3d330a585d1..9f18a275cae 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,6 +16,9 @@ // under the License. package org.apache.cloudstack.api.command.admin.swift; +import java.util.HashMap; +import java.util.Map; + import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -24,14 +27,14 @@ 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 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"; @@ -88,21 +91,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(getUrl()); + Map details = new HashMap(); + details.put(ApiConstants.ACCOUNT, getAccount()); + details.put(ApiConstants.USERNAME, getUsername()); + details.put(ApiConstants.KEY, getKey()); + + + try{ + ImageStore result = _storageService.discoverImageStore(cmd); + ImageStoreResponse storeResponse = null; + if (result != null ) { + storeResponse = _responseGenerator.createImageStoreResponse(result); + storeResponse.setResponseName(getCommandName()); + storeResponse.setObjectName("secondarystorage"); + 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 9e923d01acc..448cfd43594 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,24 +16,19 @@ // under the License. package org.apache.cloudstack.api.command.admin.swift; -import java.util.ArrayList; -import java.util.List; - import org.apache.log4j.Logger; 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 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"; @@ -66,20 +61,11 @@ 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); + setResponseObject(response); } } 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 12be54fb93d..f005efddf74 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 @@ -81,7 +81,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/ExtractIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java index 5dfa41cb2bd..4d51e63cbc8 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 @@ -112,10 +112,12 @@ public class ExtractIsoCmd extends BaseAsyncCmd { return s_name; } + @Override public ApiCommandJobType getInstanceType() { return ApiCommandJobType.Iso; } + @Override public Long getInstanceId() { return getId(); } @@ -124,12 +126,12 @@ public class ExtractIsoCmd extends BaseAsyncCmd { public void execute(){ try { CallContext.current().setEventDetails(getEventDescription()); - Long uploadId = _templateService.extract(this); - if (uploadId != null){ - ExtractResponse response = _responseGenerator.createExtractResponse(uploadId, id, zoneId, getEntityOwnerId(), mode); + 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); + setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract iso"); } 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 a12b8f6c697..d85bff66e24 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 @@ -149,16 +149,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 300458fc980..df102109e75 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 @@ -94,6 +94,9 @@ public class RegisterIsoCmd extends BaseCmd { description="Image store uuid") private String imageStoreUuid; + @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if iso contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory") + protected Boolean isDynamicallyScalable; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -150,6 +153,10 @@ public class RegisterIsoCmd extends BaseCmd { return this.imageStoreUuid; } + public Boolean isDynamicallyScalable() { + return isDynamicallyScalable == null ? false : isDynamicallyScalable; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -174,7 +181,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 74c3ca4251f..c8231cf2805 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 @@ -67,9 +67,9 @@ 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); + TemplateResponse response = _responseGenerator.createTemplateUpdateResponse(result); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java index 11236382336..a944bebab65 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java @@ -36,7 +36,7 @@ import com.cloud.user.Account; public class RevokeSecurityGroupEgressCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RevokeSecurityGroupEgressCmd.class.getName()); - private static final String s_name = "revokesecuritygroupegress"; + private static final String s_name = "revokesecuritygroupegressresponse"; // /////////////////////////////////////////////////// // ////////////// API parameters ///////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java b/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java index f2ad58fe71c..414334e0d22 100644 --- a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java @@ -36,7 +36,7 @@ import com.cloud.user.Account; public class RevokeSecurityGroupIngressCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RevokeSecurityGroupIngressCmd.class.getName()); - private static final String s_name = "revokesecuritygroupingress"; + private static final String s_name = "revokesecuritygroupingressresponse"; // /////////////////////////////////////////////////// // ////////////// API parameters ///////////////////// 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 4b5a26a7f33..b1b9e0ce91f 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 @@ -65,7 +65,7 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { description = "policy id of the snapshot, if this is null, then use MANUAL_POLICY.") private Long policyId; - private String syncObjectType = BaseAsyncCmd.snapshotHostSyncObject; + private final String syncObjectType = BaseAsyncCmd.snapshotHostSyncObject; // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// @@ -153,10 +153,10 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { - Snapshot snapshot = _snapshotService.allocSnapshot(getVolumeId(), getPolicyId()); + Snapshot snapshot = _volumeService.allocSnapshot(getVolumeId(), getPolicyId()); if (snapshot != null) { - this.setEntityId(snapshot.getId()); - this.setEntityUuid(snapshot.getUuid()); + setEntityId(snapshot.getId()); + setEntityUuid(snapshot.getUuid()); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot"); } @@ -166,15 +166,19 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { public void execute() { s_logger.info("VOLSS: createSnapshotCmd starts:" + System.currentTimeMillis()); CallContext.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(getVolumeId(), getPolicyId(), getEntityId(), _accountService.getAccount(getEntityOwnerId())); + if (snapshot != null) { + SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot); + response.setResponseName(getCommandName()); + 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); } - s_logger.info("VOLSS: backupSnapshotCmd finishes:" + System.currentTimeMillis()); } 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 aa1da4fb93b..4ef2f736db6 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/ExtractTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java index 15cc0533185..fbaacdc9357 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 @@ -113,10 +113,12 @@ public class ExtractTemplateCmd extends BaseAsyncCmd { return "extracting template: " + getId() + " from zone: " + getZoneId(); } + @Override public ApiCommandJobType getInstanceType() { return ApiCommandJobType.Template; } + @Override public Long getInstanceId() { return getId(); } @@ -125,11 +127,11 @@ public class ExtractTemplateCmd extends BaseAsyncCmd { public void execute(){ try { CallContext.current().setEventDetails(getEventDescription()); - Long uploadId = _templateService.extract(this); - if (uploadId != null){ - ExtractResponse response = _responseGenerator.createExtractResponse(uploadId, id, zoneId, getEntityOwnerId(), mode); + String uploadUrl = _templateService.extract(this); + if (uploadUrl != null) { + ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl); response.setResponseName(getCommandName()); - this.setResponseObject(response); + setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract template"); } 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 b764b6d24f8..264b9d5cff3 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 @@ -29,6 +29,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.cloudstack.context.CallContext; @@ -120,18 +121,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 9905bb1fa91..698b0c4e361 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 @@ -112,13 +112,12 @@ public class RegisterTemplateCmd extends BaseCmd { 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; + @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory") + protected Boolean isDynamicallyScalable; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -195,9 +194,6 @@ public class RegisterTemplateCmd extends BaseCmd { return templateTag; } - public String getImageStoreUuid() { - return this.imageStoreUuid; - } public Map getDetails() { if (details == null || details.isEmpty()) { @@ -209,6 +205,10 @@ public class RegisterTemplateCmd extends BaseCmd { return params; } + public Boolean isDynamicallyScalable() { + return isDynamicallyScalable == null ? false : isDynamicallyScalable; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -238,7 +238,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 a888c3c5d38..dd5dc6a8744 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 @@ -67,9 +67,9 @@ 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); + TemplateResponse response = _responseGenerator.createTemplateUpdateResponse(result); response.setObjectName("template"); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java index 9ff38ea1f95..194481d274c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java @@ -68,6 +68,9 @@ public class UpdateVMCmd extends BaseCmd{ @Parameter(name=ApiConstants.DISPLAY_VM, type=CommandType.BOOLEAN, description="an optional field, whether to the display the vm to the end user or not.") private Boolean displayVm; + @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory") + protected Boolean isDynamicallyScalable; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -96,6 +99,10 @@ public class UpdateVMCmd extends BaseCmd{ return displayVm; } + public Boolean isDynamicallyScalable() { + return isDynamicallyScalable; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// 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 5dd32ad97d0..f8f70a91274 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 @@ -118,7 +118,7 @@ public class CreateVolumeCmd extends BaseAsyncCreateCmd { } public Boolean getDisplayVolume() { - return displayVolume; + return displayVolume != null ? displayVolume : Boolean.TRUE; } ///////////////////////////////////////////////////// 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 cc62d9cdc3f..8d34cf9019c 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 @@ -16,8 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; -import java.net.URISyntaxException; - import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; @@ -96,10 +94,12 @@ public class ExtractVolumeCmd extends BaseAsyncCmd { return s_name; } + @Override public ApiCommandJobType getInstanceType() { return ApiCommandJobType.Volume; } + @Override public Long getInstanceId() { return getId(); } @@ -127,11 +127,9 @@ public class ExtractVolumeCmd extends BaseAsyncCmd { @Override public void execute(){ - try { - CallContext.current().setEventDetails("Volume Id: "+getId()); - Long uploadId = _mgr.extractVolume(this); - if (uploadId != null){ - Upload uploadInfo = _entityMgr.findById(Upload.class, uploadId); + CallContext.current().setEventDetails("Volume Id: " + getId()); + String uploadUrl = _volumeService.extractVolume(this); + if (uploadUrl != null) { ExtractResponse response = new ExtractResponse(); response.setResponseName(getCommandName()); response.setObjectName("volume"); @@ -142,18 +140,13 @@ public class ExtractVolumeCmd extends BaseAsyncCmd { response.setZoneId(zone.getUuid()); response.setZoneName(zone.getName()); response.setMode(mode); - response.setUploadId(uploadInfo.getUuid()); - response.setState(uploadInfo.getUploadState().toString()); + response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString()); Account account = _entityMgr.findById(Account.class, getEntityOwnerId()); response.setAccountId(account.getUuid()); - response.setUrl(uploadInfo.getUploadUrl()); - this.setResponseObject(response); + response.setUrl(uploadUrl); + 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()); - } } } 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/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java index 88b507af952..3a8c799622b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java @@ -51,8 +51,8 @@ public class ListZonesByCmd extends BaseListCmd { @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the zone") private String name; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; + @Parameter(name=ApiConstants.NETWORK_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") + private String networkType; @Parameter(name=ApiConstants.SHOW_CAPACITIES, type=CommandType.BOOLEAN, description="flag to display the capacity of the zones") private Boolean showCapacities; @@ -77,8 +77,8 @@ public class ListZonesByCmd extends BaseListCmd { return name; } - public String getZoneType() { - return zoneType; + public String getNetworkType() { + return networkType; } public Boolean getShowCapacities() { diff --git a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java index 5d9bb054b8c..c9e909b2bad 100644 --- a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java @@ -48,9 +48,6 @@ public class ClusterResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the cluster") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName("hypervisortype") @Param(description="the hypervisor type of the cluster") private String hypervisorType; @@ -120,10 +117,6 @@ public class ClusterResponse extends BaseResponse { this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getClusterType() { return clusterType; } diff --git a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java index 6f34a36d636..af2124f3e2e 100644 --- a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java @@ -59,6 +59,18 @@ public class DiskOfferingResponse extends BaseResponse { @SerializedName("storagetype") @Param(description="the storage type for this disk offering") private String storageType; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the disk offering") + private Long iopsWriteRate; + @SerializedName("displayoffering") @Param(description="whether to display the offering to the end user or not.") private Boolean displayOffering; @@ -150,4 +162,20 @@ public class DiskOfferingResponse extends BaseResponse { public void setStorageType(String storageType) { this.storageType = storageType; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } } diff --git a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java index 2161ac52a4d..b85e3858caf 100644 --- a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java @@ -42,9 +42,6 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name for the router") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName(ApiConstants.DNS1) @Param(description="the first DNS for the router") private String dns1; @@ -188,14 +185,6 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView this.zoneName = zoneName; } - public String getZoneType() { - return zoneType; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setDns1(String dns1) { this.dns1 = dns1; } diff --git a/api/src/org/apache/cloudstack/api/response/HostResponse.java b/api/src/org/apache/cloudstack/api/response/HostResponse.java index e4eb01b8962..4cb2b1aa6dd 100644 --- a/api/src/org/apache/cloudstack/api/response/HostResponse.java +++ b/api/src/org/apache/cloudstack/api/response/HostResponse.java @@ -61,9 +61,6 @@ public class HostResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the host") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName(ApiConstants.POD_ID) @Param(description="the Pod ID of the host") private String podId; @@ -213,10 +210,6 @@ public class HostResponse extends BaseResponse { this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setPodId(String podId) { this.podId = podId; } diff --git a/api/src/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java b/api/src/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java new file mode 100644 index 00000000000..6f90f0ff8f7 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/ImageStoreDetailResponse.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.api.response; + +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +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 image store") + private String value; + + public ImageStoreDetailResponse(){ + super(); + } + + public ImageStoreDetailResponse(String name, String val){ + super(); + this.name = name; + this.value = val; + } + + 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; + } + + @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; + ImageStoreDetailResponse other = (ImageStoreDetailResponse) 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/ImageStoreResponse.java b/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java new file mode 100644 index 00000000000..04a375f467c --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java @@ -0,0 +1,149 @@ +// 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.LinkedHashSet; +import java.util.Set; + +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.ImageStore; +import com.cloud.storage.ScopeType; +import com.google.gson.annotations.SerializedName; + +@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 image store") + private String zoneId; + + @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the image store") + private String zoneName; + + @SerializedName("name") @Param(description="the name of the image store") + private String name; + + @SerializedName("url") @Param(description="the url of the image store") + private String url; + + @SerializedName("protocol") @Param(description="the protocol of the image store") + private String protocol; + + @SerializedName("providername") @Param(description="the provider name of the image store") + private String providerName; + + @SerializedName("scope") @Param(description="the scope of the image store") + private ScopeType scope; + + @SerializedName("details") @Param(description="the details of the image store") + private Set details; + + + public ImageStoreResponse(){ + this.details = new LinkedHashSet(); + } + + @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 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 getScope() { + return scope; + } + + public void setScope(ScopeType type) { + this.scope = type; + } + + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public Set getDetails() { + return details; + } + + public void setDetails(Set details) { + this.details = details; + } + + public void addDetail(ImageStoreDetailResponse detail){ + this.details.add(detail); + } + + + +} diff --git a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java index fddaa7550e2..fb4c36f2e80 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java @@ -89,6 +89,9 @@ public class NetworkOfferingResponse extends BaseResponse { @SerializedName(ApiConstants.DETAILS) @Param(description="additional key/value details tied with network offering", since="4.2.0") private Map details; + @SerializedName(ApiConstants.EGRESS_DEFAULT_POLICY) @Param(description="true if network offering supports persistent networks, false otherwise") + private Boolean egressDefaultPolicy; + public void setId(String id) { this.id = id; @@ -167,4 +170,8 @@ public class NetworkOfferingResponse extends BaseResponse { this.details = details; } + public void setEgressDefaultPolicy(Boolean egressDefaultPolicy) { + this.egressDefaultPolicy = egressDefaultPolicy; + } + } diff --git a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java index 3a8b8752174..f9be96f2f80 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java @@ -68,9 +68,6 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone the network belongs to") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the networktype of the zone the network belongs to") - private String zoneType; - @SerializedName("networkofferingid") @Param(description="network offering id the network is created from") private String networkOfferingId; @@ -310,10 +307,6 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setCidr(String cidr) { this.cidr = cidr; } diff --git a/api/src/org/apache/cloudstack/api/response/PodResponse.java b/api/src/org/apache/cloudstack/api/response/PodResponse.java index 8f78cb0025f..89ac9de76fb 100644 --- a/api/src/org/apache/cloudstack/api/response/PodResponse.java +++ b/api/src/org/apache/cloudstack/api/response/PodResponse.java @@ -41,9 +41,6 @@ public class PodResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the Pod") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName("gateway") @Param(description="the gateway of the Pod") private String gateway; @@ -90,10 +87,6 @@ public class PodResponse extends BaseResponse { return zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setZoneName(String zoneName) { this.zoneName = zoneName; } diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index 2c596a44003..41a9b795923 100644 --- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -86,6 +86,18 @@ public class ServiceOfferingResponse extends BaseResponse { @SerializedName(ApiConstants.NETWORKRATE) @Param(description="data transfer rate in megabits per second allowed.") private Integer networkRate; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the service offering") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the service offering") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the service offering") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the service offering") + private Long iopsWriteRate; + @SerializedName(ApiConstants.DEPLOYMENT_PLANNER) @Param(description="deployment strategy used to deploy VM.") private String deploymentPlanner; @@ -247,4 +259,20 @@ public class ServiceOfferingResponse extends BaseResponse { public void setVolatileVm(boolean isVolatile) { this.isVolatile = isVolatile; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } } diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java index ffb6002c8fb..2abc7bc88b0 100644 --- a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java @@ -89,14 +89,6 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe @Param(description = "id of the availability zone") private String zoneId; - @SerializedName(ApiConstants.ZONE_NAME) - @Param(description = "name of the availability zone") - private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) - @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class) private List tags; @@ -180,13 +172,6 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe public void setZoneId(String zoneId) { this.zoneId = zoneId; } - public void setZoneName(String zoneName) { - this.zoneName = zoneName; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } public void setTags(List tags) { this.tags = tags; diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java index 57257a7535b..d7b391d43c1 100644 --- a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java +++ b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java @@ -39,8 +39,6 @@ public class StoragePoolResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the storage pool") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; @SerializedName("podid") @Param(description="the Pod ID of the storage pool") private String podId; @@ -145,14 +143,6 @@ public class StoragePoolResponse extends BaseResponse { this.zoneName = zoneName; } - public String getZoneType() { - return zoneType; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getPodId() { return podId; } diff --git a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java index 3f1d955763d..8612ff28a99 100644 --- a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java @@ -41,9 +41,6 @@ public class SystemVmResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name for the system VM") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName("dns1") @Param(description="the first DNS for the system VM") private String dns1; @@ -149,14 +146,6 @@ public class SystemVmResponse extends BaseResponse { this.zoneName = zoneName; } - public String getZoneType() { - return zoneType; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getDns1() { return dns1; } diff --git a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java index 8bbfe479bcd..00a56682078 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 com.google.gson.annotations.SerializedName; @@ -32,7 +34,7 @@ import com.cloud.template.VirtualMachineTemplate; @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; @@ -83,15 +85,14 @@ 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; @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone for this template") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the networktype of the zone for this template") - private String zoneType; - @SerializedName(ApiConstants.STATUS) @Param(description="the status of the template") private String status; @@ -137,12 +138,24 @@ 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; + @SerializedName(ApiConstants.IS_DYNAMICALLY_SCALABLE) @Param(description="true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory") + private Boolean isDynamicallyScalable; + + public TemplateResponse(){ + zones = new LinkedHashSet(); + tags = new LinkedHashSet(); + } + + @Override public String getObjectId() { return this.getId(); @@ -160,10 +173,6 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setAccountId(String accountId) { this.accountId = accountId; } @@ -296,12 +305,31 @@ 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 void setDynamicallyScalable(boolean isDynamicallyScalable) { + this.isDynamicallyScalable = isDynamicallyScalable; + } + + 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/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index ed7b7dfc4c5..e6f52226d64 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -80,9 +80,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the availability zone for the virtual machine") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the network type of the availability zone for the virtual machine") - private String zoneType; - @SerializedName(ApiConstants.HOST_ID) @Param(description="the ID of the host for the virtual machine") private String hostId; @@ -192,6 +189,9 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.DISPLAY_VM) @Param(description="an optional field whether to the display the vm to the end user or not.") private Boolean displayVm; + @SerializedName(ApiConstants.IS_DYNAMICALLY_SCALABLE) @Param(description="true if vm contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory.") + private Boolean isDynamicallyScalable; + public UserVmResponse(){ securityGroupList = new LinkedHashSet(); nics = new LinkedHashSet(); @@ -273,10 +273,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setHostId(String hostId) { this.hostId = hostId; } @@ -439,4 +435,8 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp this.affinityGroupList.add(affinityGroup); } + public void setDynamicallyScalable(boolean isDynamicallyScalable) { + this.isDynamicallyScalable = isDynamicallyScalable; + } + } diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java index 47e620f55fb..a006e57e0f7 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java @@ -48,10 +48,6 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @Param(description = "name of the availability zone") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) - @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName(ApiConstants.TYPE) @Param(description = "type of the disk volume (ROOT or DATADISK)") private String volumeType; @@ -110,6 +106,18 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @Param(description = "shared or local storage") private String storageType; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the disk volume") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the disk volume") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the disk volume") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the disk volume") + private Long iopsWriteRate; + @SerializedName(ApiConstants.HYPERVISOR) @Param(description = "Hypervisor the volume belongs to") private String hypervisor; @@ -205,10 +213,6 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setVolumeType(String volumeType) { this.volumeType = volumeType; } @@ -258,6 +262,38 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity this.storageType = storageType; } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + public void setHypervisor(String hypervisor) { this.hypervisor = hypervisor; } diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java index 73e393b069f..da843a9bddd 100644 --- a/api/src/org/apache/cloudstack/query/QueryService.java +++ b/api/src/org/apache/cloudstack/query/QueryService.java @@ -20,11 +20,14 @@ import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; +import org.apache.cloudstack.api.command.admin.storage.ListCacheStoresCmd; +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; 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; @@ -32,6 +35,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.ListResourceDetailsCmd; @@ -75,6 +79,10 @@ public interface QueryService { public ListResponse searchForStoragePools(ListStoragePoolsCmd cmd); + public ListResponse searchForImageStores(ListImageStoresCmd cmd); + + public ListResponse searchForCacheStores(ListCacheStoresCmd cmd); + public ListResponse searchForAccounts(ListAccountsCmd cmd); public ListResponse searchForAsyncJobs(ListAsyncJobsCmd cmd); @@ -85,6 +93,9 @@ public interface QueryService { public ListResponse listDataCenters(ListZonesByCmd cmd); + public ListResponse listTemplates(ListTemplatesCmd cmd); + + public ListResponse listIsos(ListIsosCmd cmd); public ListResponse listAffinityGroups(Long affinityGroupId, String affinityGroupName, String affinityGroupType, Long vmId, String accountName, Long domainId, boolean isRecursive, boolean listAll, Long startIndex, Long pageSize); 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()); - } - - } - -} diff --git a/awsapi/src/com/cloud/bridge/model/CloudStackServiceOfferingVO.java b/awsapi/src/com/cloud/bridge/model/CloudStackServiceOfferingVO.java index de2941e23db..f63301a437a 100644 --- a/awsapi/src/com/cloud/bridge/model/CloudStackServiceOfferingVO.java +++ b/awsapi/src/com/cloud/bridge/model/CloudStackServiceOfferingVO.java @@ -30,7 +30,10 @@ public class CloudStackServiceOfferingVO { @Id @Column(name="id") private String id; - + + @Column(name="uuid") + private String uuid; + @Column(name="name") private String name; @@ -61,7 +64,9 @@ public class CloudStackServiceOfferingVO { public void setDomainId(String domainId) { this.domainId = domainId; } - + public String getUuid() { + return uuid; + } } diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java index 6770a9cc514..bc77ea1d886 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java @@ -54,7 +54,8 @@ public class CloudStackConfigurationDaoImpl extends GenericDaoBase searchByID = createSearchBuilder(); - searchByID.and("id", searchByID.entity().getName(), SearchCriteria.Op.EQ); + searchByID.and("uuid", searchByID.entity().getUuid(), SearchCriteria.Op.EQ); searchByID.done(); Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { txn.start(); SearchCriteria sc = searchByID.create(); - sc.setParameters("id", id); + sc.setParameters("uuid", id); return findOneBy(sc); }finally { + txn.commit(); txn.close(); } diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackUserDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackUserDaoImpl.java index 5aac3960d02..f7e1da65dc6 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackUserDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackUserDaoImpl.java @@ -55,6 +55,7 @@ public class CloudStackUserDaoImpl extends GenericDaoBase implements MHost SearchCriteria sc = NameSearch.create(); sc.setParameters("MHostKey", hostKey); return findOneBy(sc); - - }finally { - txn.close(); - } + } finally { + txn.commit(); + txn.close(); + } } @Override diff --git a/awsapi/src/com/cloud/bridge/persist/dao/OfferingDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/OfferingDaoImpl.java index cce0f838f88..ea7d264f80c 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/OfferingDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/OfferingDaoImpl.java @@ -43,7 +43,8 @@ public class OfferingDaoImpl extends GenericDaoBase impl try { txn.start(); return listAll().size(); - }finally { + } finally { + txn.commit(); txn.close(); } @@ -61,8 +62,8 @@ public class OfferingDaoImpl extends GenericDaoBase impl SearchCriteria sc = searchByAmazon.create(); sc.setParameters("AmazonEC2Offering", amazonEC2Offering); return findOneBy(sc).getCloudstackOffering(); - } finally { + txn.commit(); txn.close(); } } @@ -79,8 +80,8 @@ public class OfferingDaoImpl extends GenericDaoBase impl SearchCriteria sc = searchByAmazon.create(); sc.setParameters("CloudStackOffering", cloudStackOffering); return findOneBy(sc).getAmazonOffering(); - } finally { + txn.commit(); txn.close(); } } @@ -109,7 +110,6 @@ public class OfferingDaoImpl extends GenericDaoBase impl offering = persist(offering); else update(offering.getID(), offering); - txn.commit(); } finally { txn.close(); diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SHostDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/SHostDaoImpl.java index 5eadd0661c1..9b6b5359759 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SHostDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SHostDaoImpl.java @@ -42,8 +42,8 @@ public class SHostDaoImpl extends GenericDaoBase implements SHost SearchCriteria sc = HostSearch.create(); sc.setParameters("Host", host); return findOneBy(sc); - - }finally { + } finally { + txn.commit(); txn.close(); } @@ -62,8 +62,8 @@ public class SHostDaoImpl extends GenericDaoBase implements SHost sc.setParameters("MHostID", mhostId); sc.setParameters("ExportRoot", storageRoot); return findOneBy(sc); - - }finally { + } finally { + txn.commit(); txn.close(); } } diff --git a/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDaoImpl.java index 684b00b920f..c45886f794c 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDaoImpl.java @@ -67,6 +67,7 @@ public class UserCredentialsDaoImpl extends GenericDaoBase\u6ce8: \u65b0\u3057\u304f\u53d6\u5f97\u3057\u305f\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u306f\u4eee\u60f3\u30de\u30b7\u30f3\u5185\u3067\u624b\u52d5\u3067\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +message.select.affinity.groups=\u3053\u306e VM \u3092\u8ffd\u52a0\u3059\u308b\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.no.affinity.groups=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u304c\u3042\u308a\u307e\u305b\u3093\u3002\u6b21\u306e\u624b\u9806\u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002 +label.action.delete.nic=NIC \u306e\u524a\u9664 +message.action.delete.nic=\u3053\u306e NIC \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3082 VM \u304b\u3089\u524a\u9664\u3055\u308c\u307e\u3059\u3002 changed.item.properties=\u9805\u76ee\u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u5909\u66f4 -confirm.enable.s3=S3\u57fa\u76e4\u30bb\u30ab\u30f3\u30c0\u30ea\u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u6709\u52b9\u5316\u3059\u308b\u305f\u3081\u306b\u306f\u3001\u4ee5\u4e0b\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044 -confirm.enable.swift=Swift1 \u306e\u30b5\u30dd\u30fc\u30c8\u3092\u6709\u52b9\u306b\u3059\u308b\u306b\u306f\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +confirm.enable.s3=S3 \u30d9\u30fc\u30b9\u306e\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u30b5\u30dd\u30fc\u30c8\u3092\u6709\u52b9\u306b\u3059\u308b\u306b\u306f\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +confirm.enable.swift=Swift \u306e\u30b5\u30dd\u30fc\u30c8\u3092\u6709\u52b9\u306b\u3059\u308b\u306b\u306f\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 error.could.not.enable.zone=\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f error.installWizard.message=\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u623b\u3063\u3066\u30a8\u30e9\u30fc\u3092\u4fee\u6b63\u3067\u304d\u307e\u3059\u3002 error.invalid.username.password=\u7121\u52b9\u306a\u30e6\u30fc\u30b6\u30fc\u540d\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9 @@ -30,13 +34,13 @@ error.please.specify.physical.network.tags=\u3053\u306e\u7269\u7406\u30cd\u30c3\ error.session.expired=\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u307e\u3057\u305f\u3002 error.something.went.wrong.please.correct.the.following=\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u6b21\u306e\u5185\u5bb9\u3092\u4fee\u6b63\u3057\u3066\u304f\u3060\u3055\u3044 error.unable.to.reach.management.server=\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u3068\u901a\u4fe1\u3067\u304d\u307e\u305b\u3093 -error.unresolved.internet.name=\u3042\u306a\u305f\u306e\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u540d\u306f\u89e3\u6c7a\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002 +error.unresolved.internet.name=\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u540d\u3092\u89e3\u6c7a\u3067\u304d\u307e\u305b\u3093\u3002 extractable=\u62bd\u51fa\u53ef\u80fd -force.delete.domain.warning=\u8b66\u544a: \u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3059\u308b\u3068\u3001\u3059\u3079\u3066\u306e\u5b50\u30c9\u30e1\u30a4\u30f3\u304a\u3088\u3073\u95a2\u9023\u3059\u308b\u3059\u3079\u3066\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3068\u305d\u306e\u30ea\u30bd\u30fc\u30b9\u304c\u524a\u9664\u3055\u308c\u307e\u3059\u3002 +force.delete.domain.warning=\u8b66\u544a\: \u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3059\u308b\u3068\u3001\u3059\u3079\u3066\u306e\u5b50\u30c9\u30e1\u30a4\u30f3\u304a\u3088\u3073\u95a2\u9023\u3059\u308b\u3059\u3079\u3066\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3068\u305d\u306e\u30ea\u30bd\u30fc\u30b9\u304c\u524a\u9664\u3055\u308c\u307e\u3059\u3002 force.delete=\u5f37\u5236\u524a\u9664 -force.remove.host.warning=\u8b66\u544a: \u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3059\u308b\u3068\u3001\u5b9f\u884c\u4e2d\u306e\u3059\u3079\u3066\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u304c\u5f37\u5236\u7684\u306b\u505c\u6b62\u3055\u308c\u3001\u30af\u30e9\u30b9\u30bf\u30fc\u304b\u3089\u3053\u306e\u30db\u30b9\u30c8\u304c\u5f37\u5236\u7684\u306b\u89e3\u9664\u3055\u308c\u307e\u3059\u3002 +force.remove.host.warning=\u8b66\u544a\: \u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3059\u308b\u3068\u3001\u5b9f\u884c\u4e2d\u306e\u3059\u3079\u3066\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u304c\u5f37\u5236\u7684\u306b\u505c\u6b62\u3055\u308c\u3001\u30af\u30e9\u30b9\u30bf\u30fc\u304b\u3089\u3053\u306e\u30db\u30b9\u30c8\u304c\u5f37\u5236\u7684\u306b\u89e3\u9664\u3055\u308c\u307e\u3059\u3002 force.remove=\u5f37\u5236\u89e3\u9664 -force.stop.instance.warning=\u8b66\u544a: \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u5f37\u5236\u505c\u6b62\u306f\u3001\u6700\u7d42\u624b\u6bb5\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30c7\u30fc\u30bf\u3092\u640d\u5931\u3059\u308b\u3060\u3051\u3067\u306a\u304f\u3001\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u52d5\u4f5c\u304c\u4e00\u8cab\u3057\u306a\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 +force.stop.instance.warning=\u8b66\u544a\: \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u5f37\u5236\u505c\u6b62\u306f\u3001\u6700\u7d42\u624b\u6bb5\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30c7\u30fc\u30bf\u3092\u640d\u5931\u3059\u308b\u3060\u3051\u3067\u306a\u304f\u3001\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u52d5\u4f5c\u304c\u4e00\u8cab\u3057\u306a\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 force.stop=\u5f37\u5236\u505c\u6b62 ICMP.code=ICMP \u30b3\u30fc\u30c9 ICMP.type=ICMP \u306e\u7a2e\u985e @@ -48,20 +52,21 @@ label.account.and.security.group=\u30a2\u30ab\u30a6\u30f3\u30c8\u3001\u30bb\u30a label.account.id=\u30a2\u30ab\u30a6\u30f3\u30c8 ID label.account.name=\u30a2\u30ab\u30a6\u30f3\u30c8\u540d label.account.specific=\u30a2\u30ab\u30a6\u30f3\u30c8\u56fa\u6709 -label.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8 label.account=\u30a2\u30ab\u30a6\u30f3\u30c8 +label.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8 label.acquire.new.ip=\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u306e\u53d6\u5f97 +label.acquire.new.secondary.ip=\u30bb\u30ab\u30f3\u30c0\u30ea IP \u30a2\u30c9\u30ec\u30b9\u306e\u53d6\u5f97 label.action.attach.disk.processing=\u30c7\u30a3\u30b9\u30af\u3092\u30a2\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... label.action.attach.disk=\u30c7\u30a3\u30b9\u30af\u306e\u30a2\u30bf\u30c3\u30c1 -label.action.attach.iso=ISO \u306e\u30a2\u30bf\u30c3\u30c1 label.action.attach.iso.processing=ISO \u3092\u30a2\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... +label.action.attach.iso=ISO \u306e\u30a2\u30bf\u30c3\u30c1 label.action.cancel.maintenance.mode.processing=\u4fdd\u5b88\u30e2\u30fc\u30c9\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u3066\u3044\u307e\u3059... label.action.cancel.maintenance.mode=\u4fdd\u5b88\u30e2\u30fc\u30c9\u306e\u30ad\u30e3\u30f3\u30bb\u30eb label.action.change.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5909\u66f4 label.action.change.service.processing=\u30b5\u30fc\u30d3\u30b9\u3092\u5909\u66f4\u3057\u3066\u3044\u307e\u3059... label.action.change.service=\u30b5\u30fc\u30d3\u30b9\u306e\u5909\u66f4 -label.action.copy.ISO=ISO \u306e\u30b3\u30d4\u30fc label.action.copy.ISO.processing=ISO \u3092\u30b3\u30d4\u30fc\u3057\u3066\u3044\u307e\u3059... +label.action.copy.ISO=ISO \u306e\u30b3\u30d4\u30fc label.action.copy.template.processing=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30b3\u30d4\u30fc\u3057\u3066\u3044\u307e\u3059... label.action.copy.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30b3\u30d4\u30fc label.action.create.template.from.vm=VM \u304b\u3089\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u4f5c\u6210 @@ -84,10 +89,10 @@ label.action.delete.firewall.processing=\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30 label.action.delete.firewall=\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u898f\u5247\u306e\u524a\u9664 label.action.delete.ingress.rule.processing=\u53d7\u4fe1\u898f\u5247\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.ingress.rule=\u53d7\u4fe1\u898f\u5247\u306e\u524a\u9664 -label.action.delete.IP.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u524a\u9664 label.action.delete.IP.range.processing=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... -label.action.delete.ISO=ISO \u306e\u524a\u9664 +label.action.delete.IP.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u524a\u9664 label.action.delete.ISO.processing=ISO \u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... +label.action.delete.ISO=ISO \u306e\u524a\u9664 label.action.delete.load.balancer.processing=\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.delete.load.balancer=\u8ca0\u8377\u5206\u6563\u898f\u5247\u306e\u524a\u9664 label.action.delete.network.processing=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... @@ -121,8 +126,8 @@ label.action.destroy.systemvm.processing=\u30b7\u30b9\u30c6\u30e0 VM \u3092\u783 label.action.destroy.systemvm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u7834\u68c4 label.action.detach.disk.processing=\u30c7\u30a3\u30b9\u30af\u3092\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... label.action.detach.disk=\u30c7\u30a3\u30b9\u30af\u306e\u30c7\u30bf\u30c3\u30c1 -label.action.detach.iso=ISO \u306e\u30c7\u30bf\u30c3\u30c1 label.action.detach.iso.processing=ISO \u3092\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059... +label.action.detach.iso=ISO \u306e\u30c7\u30bf\u30c3\u30c1 label.action.disable.account.processing=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7121\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... label.action.disable.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u7121\u52b9\u5316 label.action.disable.cluster.processing=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u7121\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... @@ -161,7 +166,7 @@ label.action.edit.zone=\u30be\u30fc\u30f3\u306e\u7de8\u96c6 label.action.enable.account.processing=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... label.action.enable.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u6709\u52b9\u5316 label.action.enable.cluster.processing=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... -label.action.enable.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u6709\u52b9\u5316 +label.action.enable.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u6709\u52b9\u5316 label.action.enable.maintenance.mode.processing=\u4fdd\u5b88\u30e2\u30fc\u30c9\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059... label.action.enable.maintenance.mode=\u4fdd\u5b88\u30e2\u30fc\u30c9\u306e\u6709\u52b9\u5316 label.action.enable.nexusVswitch=Nexus 1000V \u306e\u6709\u52b9\u5316 @@ -198,12 +203,14 @@ label.action.reboot.systemvm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u518d\u8d77\u52d label.action.recurring.snapshot=\u5b9a\u671f\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 label.action.register.iso=ISO \u306e\u767b\u9332 label.action.register.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u767b\u9332 -label.action.release.ip=IP \u30a2\u30c9\u30ec\u30b9\u306e\u89e3\u653e label.action.release.ip.processing=IP \u30a2\u30c9\u30ec\u30b9\u3092\u89e3\u653e\u3057\u3066\u3044\u307e\u3059... +label.action.release.ip=IP \u30a2\u30c9\u30ec\u30b9\u306e\u89e3\u653e label.action.remove.host.processing=\u30db\u30b9\u30c8\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.action.remove.host=\u30db\u30b9\u30c8\u306e\u524a\u9664 label.action.reset.password.processing=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u3066\u3044\u307e\u3059... label.action.reset.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u30ea\u30bb\u30c3\u30c8 +label.action.resize.volume.processing=\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30b5\u30a4\u30ba\u3092\u5909\u66f4\u3057\u3066\u3044\u307e\u3059... +label.action.resize.volume=\u30dc\u30ea\u30e5\u30fc\u30e0 \u30b5\u30a4\u30ba\u306e\u5909\u66f4 label.action.resource.limits=\u30ea\u30bd\u30fc\u30b9\u5236\u9650 label.action.restore.instance.processing=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u5fa9\u5143\u3057\u3066\u3044\u307e\u3059... label.action.restore.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u5fa9\u5143 @@ -219,22 +226,27 @@ label.action.stop.router.processing=\u30eb\u30fc\u30bf\u30fc\u3092\u505c\u6b62\u label.action.stop.router=\u30eb\u30fc\u30bf\u30fc\u306e\u505c\u6b62 label.action.stop.systemvm.processing=\u30b7\u30b9\u30c6\u30e0 VM \u3092\u505c\u6b62\u3057\u3066\u3044\u307e\u3059... label.action.stop.systemvm=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u505c\u6b62 -label.actions=\u64cd\u4f5c label.action.take.snapshot.processing=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059.... label.action.take.snapshot=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u4f5c\u6210 label.action.unmanage.cluster.processing=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u975e\u7ba1\u7406\u5bfe\u8c61\u306b\u3057\u3066\u3044\u307e\u3059... label.action.unmanage.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u975e\u7ba1\u7406\u5bfe\u8c61\u5316 -label.action.update.OS.preference=OS \u57fa\u672c\u8a2d\u5b9a\u306e\u66f4\u65b0 label.action.update.OS.preference.processing=OS \u57fa\u672c\u8a2d\u5b9a\u3092\u66f4\u65b0\u3057\u3066\u3044\u307e\u3059... +label.action.update.OS.preference=OS \u57fa\u672c\u8a2d\u5b9a\u306e\u66f4\u65b0 label.action.update.resource.count.processing=\u30ea\u30bd\u30fc\u30b9\u6570\u3092\u66f4\u65b0\u3057\u3066\u3044\u307e\u3059... label.action.update.resource.count=\u30ea\u30bd\u30fc\u30b9\u6570\u306e\u66f4\u65b0 +label.action.vmsnapshot.create=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u4f5c\u6210 +label.action.vmsnapshot.delete=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u524a\u9664 +label.action.vmsnapshot.revert=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u5143\u306b\u623b\u3059 +label.actions=\u64cd\u4f5c label.activate.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u30a2\u30af\u30c6\u30a3\u30d6\u5316 label.active.sessions=\u30a2\u30af\u30c6\u30a3\u30d6\u306a\u30bb\u30c3\u30b7\u30e7\u30f3 -label.add.accounts.to=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0\u5148: -label.add.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0 label.add.account.to.project=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u8ffd\u52a0 label.add.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0 +label.add.accounts.to=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0\u5148: +label.add.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0 label.add.ACL=ACL \u306e\u8ffd\u52a0 +label.add.affinity.group=\u65b0\u3057\u3044\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u8ffd\u52a0 +label.add.BigSwitchVns.device=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0 label.add.by.cidr=CIDR \u3067\u8ffd\u52a0 label.add.by.group=\u30b0\u30eb\u30fc\u30d7\u3067\u8ffd\u52a0 label.add.by=\u8ffd\u52a0\u5358\u4f4d @@ -248,17 +260,8 @@ label.add.F5.device=F5 \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 label.add.firewall=\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u898f\u5247\u306e\u8ffd\u52a0 label.add.guest.network=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 label.add.host=\u30db\u30b9\u30c8\u306e\u8ffd\u52a0 -label.adding.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.adding.failed=\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f -label.adding.pod=\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.adding.processing=\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059... label.add.ingress.rule=\u53d7\u4fe1\u898f\u5247\u306e\u8ffd\u52a0 -label.adding.succeeded=\u8ffd\u52a0\u3057\u307e\u3057\u305f -label.adding=\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.adding.user=\u30e6\u30fc\u30b6\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -label.adding.zone=\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 label.add.ip.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u8ffd\u52a0 -label.additional.networks=\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.add.load.balancer=\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u306e\u8ffd\u52a0 label.add.more=\u305d\u306e\u307b\u304b\u306e\u9805\u76ee\u306e\u8ffd\u52a0 label.add.netScaler.device=Netscaler \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0 @@ -271,11 +274,12 @@ label.add.new.gateway=\u65b0\u3057\u3044\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30 label.add.new.NetScaler=\u65b0\u3057\u3044 NetScaler \u306e\u8ffd\u52a0 label.add.new.SRX=\u65b0\u3057\u3044 SRX \u306e\u8ffd\u52a0 label.add.new.tier=\u65b0\u3057\u3044\u968e\u5c64\u306e\u8ffd\u52a0 -label.add.NiciraNvp.device=NVP\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0 +label.add.NiciraNvp.device=NVP \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0 label.add.physical.network=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8ffd\u52a0 label.add.pod=\u30dd\u30c3\u30c9\u306e\u8ffd\u52a0 label.add.port.forwarding.rule=\u30dd\u30fc\u30c8\u8ee2\u9001\u898f\u5247\u306e\u8ffd\u52a0 label.add.primary.storage=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u8ffd\u52a0 +label.add.region=\u9818\u57df\u306e\u8ffd\u52a0 label.add.resources=\u30ea\u30bd\u30fc\u30b9\u306e\u8ffd\u52a0 label.add.route=\u30eb\u30fc\u30c8\u306e\u8ffd\u52a0 label.add.rule=\u898f\u5247\u306e\u8ffd\u52a0 @@ -288,24 +292,36 @@ label.add.static.route=\u9759\u7684\u30eb\u30fc\u30c8\u306e\u8ffd\u52a0 label.add.system.service.offering=\u30b7\u30b9\u30c6\u30e0 \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u8ffd\u52a0 label.add.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u8ffd\u52a0 label.add.to.group=\u30b0\u30eb\u30fc\u30d7\u3078\u306e\u8ffd\u52a0 -label.add=\u8ffd\u52a0 label.add.user=\u30e6\u30fc\u30b6\u30fc\u306e\u8ffd\u52a0 label.add.vlan=VLAN \u306e\u8ffd\u52a0 -label.add.vms.to.lb=\u8ca0\u8377\u5206\u6563\u898f\u5247\u3078\u306e VM \u306e\u8ffd\u52a0 -label.add.vms=VM \u306e\u8ffd\u52a0 label.add.VM.to.tier=\u968e\u5c64\u3078\u306e VM \u306e\u8ffd\u52a0 label.add.vm=VM \u306e\u8ffd\u52a0 +label.add.vms.to.lb=\u8ca0\u8377\u5206\u6563\u898f\u5247\u3078\u306e VM \u306e\u8ffd\u52a0 +label.add.vms=VM \u306e\u8ffd\u52a0 label.add.volume=\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u8ffd\u52a0 label.add.vpc=VPC \u306e\u8ffd\u52a0 label.add.vpn.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u8ffd\u52a0 label.add.VPN.gateway=VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u8ffd\u52a0 label.add.vpn.user=VPN \u30e6\u30fc\u30b6\u30fc\u306e\u8ffd\u52a0 label.add.zone=\u30be\u30fc\u30f3\u306e\u8ffd\u52a0 +label.add=\u8ffd\u52a0 +label.adding.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.adding.failed=\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f +label.adding.pod=\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.adding.processing=\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059... +label.adding.succeeded=\u8ffd\u52a0\u3057\u307e\u3057\u305f +label.adding.user=\u30e6\u30fc\u30b6\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.adding.zone=\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.adding=\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +label.additional.networks=\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.admin.accounts=\u7ba1\u7406\u8005\u30a2\u30ab\u30a6\u30f3\u30c8 label.admin=\u7ba1\u7406\u8005 label.advanced.mode=\u62e1\u5f35\u30e2\u30fc\u30c9 label.advanced.search=\u9ad8\u5ea6\u306a\u691c\u7d22 label.advanced=\u62e1\u5f35 +label.affinity.group=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.affinity.groups=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.affinity=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 label.agent.password=\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8 \u30d1\u30b9\u30ef\u30fc\u30c9 label.agent.username=\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8 \u30e6\u30fc\u30b6\u30fc\u540d label.agree=\u540c\u610f\u3059\u308b @@ -313,25 +329,31 @@ label.alert=\u30a2\u30e9\u30fc\u30c8 label.algorithm=\u30a2\u30eb\u30b4\u30ea\u30ba\u30e0 label.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f label.allocation.state=\u5272\u308a\u5f53\u3066\u72b6\u614b +label.anti.affinity.group=\u30a2\u30f3\u30c1\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.anti.affinity.groups=\u30a2\u30f3\u30c1\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.anti.affinity=\u30a2\u30f3\u30c1\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 label.api.key=API \u30ad\u30fc label.apply=\u9069\u7528 label.assign.to.load.balancer=\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u306b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u5272\u308a\u5f53\u3066\u3066\u3044\u307e\u3059 label.assign=\u5272\u308a\u5f53\u3066 label.associated.network.id=\u95a2\u9023\u3065\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ID label.associated.network=\u95a2\u9023\u3065\u3051\u3089\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af -label.attached.iso=\u30a2\u30bf\u30c3\u30c1\u3055\u308c\u305f ISO -label.availability=\u53ef\u7528\u6027 +label.attached.iso=\u30a2\u30bf\u30c3\u30c1\u3055\u308c\u305f ISO +label.author.email=\u4f5c\u6210\u8005\u306e\u96fb\u5b50\u30e1\u30fc\u30eb +label.author.name=\u4f5c\u6210\u8005\u306e\u540d\u524d label.availability.zone=\u5229\u7528\u53ef\u80fd\u30be\u30fc\u30f3 +label.availability=\u53ef\u7528\u6027 label.available.public.ips=\u4f7f\u7528\u3067\u304d\u308b\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 label.available=\u4f7f\u7528\u53ef\u80fd label.back=\u623b\u308b label.bandwidth=\u5e2f\u57df\u5e45 label.basic.mode=\u57fa\u672c\u30e2\u30fc\u30c9 label.basic=\u57fa\u672c +label.bigswitch.controller.address=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u30a2\u30c9\u30ec\u30b9 label.bootable=\u8d77\u52d5\u53ef\u80fd label.broadcast.domain.range=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 \u30c9\u30e1\u30a4\u30f3\u306e\u7bc4\u56f2 label.broadcast.domain.type=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 \u30c9\u30e1\u30a4\u30f3\u306e\u7a2e\u985e -label.broadcast.uri=Broadcast URI +label.broadcast.uri=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 URI label.by.account=\u30a2\u30ab\u30a6\u30f3\u30c8 label.by.availability=\u53ef\u7528\u6027 label.by.domain=\u30c9\u30e1\u30a4\u30f3 @@ -341,12 +363,12 @@ label.by.pod=\u30dd\u30c3\u30c9 label.by.role=\u5f79\u5272 label.by.start.date=\u958b\u59cb\u65e5 label.by.state=\u72b6\u614b -label.bytes.received=\u53d7\u4fe1\u30d0\u30a4\u30c8 -label.bytes.sent=\u9001\u4fe1\u30d0\u30a4\u30c8 label.by.traffic.type=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e label.by.type.id=\u7a2e\u985e ID label.by.type=\u7a2e\u985e label.by.zone=\u30be\u30fc\u30f3 +label.bytes.received=\u53d7\u4fe1\u30d0\u30a4\u30c8 +label.bytes.sent=\u9001\u4fe1\u30d0\u30a4\u30c8 label.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb label.capacity=\u51e6\u7406\u80fd\u529b label.certificate=\u8a3c\u660e\u66f8 @@ -355,32 +377,32 @@ label.change.value=\u5024\u306e\u5909\u66f4 label.character=\u6587\u5b57 label.checksum=MD5 \u30c1\u30a7\u30c3\u30af\u30b5\u30e0 label.cidr.account=CIDR \u307e\u305f\u306f\u30a2\u30ab\u30a6\u30f3\u30c8/\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 -label.cidr=CIDR label.CIDR.list=CIDR \u4e00\u89a7 label.cidr.list=\u9001\u4fe1\u5143 CIDR label.CIDR.of.destination.network=\u5b9b\u5148\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e CIDR +label.cidr=CIDR label.clean.up=\u30af\u30ea\u30fc\u30f3 \u30a2\u30c3\u30d7 label.clear.list=\u4e00\u89a7\u306e\u6d88\u53bb label.close=\u9589\u3058\u308b label.cloud.console=\u30af\u30e9\u30a6\u30c9\u7ba1\u7406\u30b3\u30f3\u30bd\u30fc\u30eb label.cloud.managed=Cloud.com \u306b\u3088\u308b\u7ba1\u7406 label.cluster.name=\u30af\u30e9\u30b9\u30bf\u30fc\u540d -label.clusters=\u30af\u30e9\u30b9\u30bf\u30fc label.cluster.type=\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u7a2e\u985e label.cluster=\u30af\u30e9\u30b9\u30bf\u30fc +label.clusters=\u30af\u30e9\u30b9\u30bf\u30fc label.clvm=CLVM label.code=\u30b3\u30fc\u30c9 label.community=\u30b3\u30df\u30e5\u30cb\u30c6\u30a3 label.compute.and.storage=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u3068\u30b9\u30c8\u30ec\u30fc\u30b8 -label.compute.offerings=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.compute.offering=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 +label.compute.offerings=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.compute=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 label.configuration=\u69cb\u6210 label.configure.network.ACLs=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL \u306e\u69cb\u6210 -label.configure=\u69cb\u6210 label.configure.vpc=VPC \u306e\u69cb\u6210 -label.confirmation=\u78ba\u8a8d +label.configure=\u69cb\u6210 label.confirm.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u78ba\u8a8d\u5165\u529b +label.confirmation=\u78ba\u8a8d label.congratulations=\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306f\u3053\u308c\u3067\u5b8c\u4e86\u3067\u3059\u3002 label.conserve.mode=\u7bc0\u7d04\u30e2\u30fc\u30c9 label.console.proxy=\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7 @@ -389,15 +411,16 @@ label.continue=\u7d9a\u884c label.corrections.saved=\u63a5\u7d9a\u304c\u4fdd\u5b58\u3055\u308c\u307e\u3057\u305f label.cpu.allocated.for.VMs=VM \u306b\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e CPU label.cpu.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e CPU -label.CPU.cap=CPU \u5236\u9650 -label.cpu=CPU +label.CPU.cap=CPU \u4e0a\u9650 +label.cpu.limits=CPU \u5236\u9650 label.cpu.mhz=CPU (MHz) label.cpu.utilized=CPU \u4f7f\u7528\u7387 -label.created.by.system=\u30b7\u30b9\u30c6\u30e0\u4f5c\u6210 -label.created=\u4f5c\u6210\u65e5\u6642 +label.cpu=CPU label.create.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210 label.create.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u4f5c\u6210 label.create.VPN.connection=VPN \u63a5\u7d9a\u306e\u4f5c\u6210 +label.created.by.system=\u30b7\u30b9\u30c6\u30e0\u4f5c\u6210 +label.created=\u4f5c\u6210\u65e5\u6642 label.cross.zones=\u30af\u30ed\u30b9 \u30be\u30fc\u30f3 label.custom.disk.size=\u30ab\u30b9\u30bf\u30e0 \u30c7\u30a3\u30b9\u30af \u30b5\u30a4\u30ba label.daily=\u6bce\u65e5 @@ -408,20 +431,22 @@ label.day.of.week=\u6bce\u9031\u6307\u5b9a\u65e5 label.dead.peer.detection=\u505c\u6b62\u30d4\u30a2\u306e\u691c\u51fa label.decline.invitation=\u62db\u5f85\u306e\u8f9e\u9000 label.dedicated=\u5c02\u7528 -label.default=\u30c7\u30d5\u30a9\u30eb\u30c8 label.default.use=\u30c7\u30d5\u30a9\u30eb\u30c8\u4f7f\u7528 label.default.view=\u30c7\u30d5\u30a9\u30eb\u30c8 \u30d3\u30e5\u30fc +label.default=\u30c7\u30d5\u30a9\u30eb\u30c8 +label.delete.affinity.group=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u524a\u9664 +label.delete.BigSwitchVns=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664 label.delete.F5=F5 \u306e\u524a\u9664 label.delete.gateway=\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u524a\u9664 label.delete.NetScaler=NetScaler \u306e\u524a\u9664 -label.delete.NiciraNvp=NVP\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664 +label.delete.NiciraNvp=NVP \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664 label.delete.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u524a\u9664 label.delete.SRX=SRX \u306e\u524a\u9664 -label.delete=\u524a\u9664 label.delete.VPN.connection=VPN \u63a5\u7d9a\u306e\u524a\u9664 label.delete.VPN.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u524a\u9664 label.delete.VPN.gateway=VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u524a\u9664 label.delete.vpn.user=VPN \u30e6\u30fc\u30b6\u30fc\u306e\u524a\u9664 +label.delete=\u524a\u9664 label.deleting.failed=\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f label.deleting.processing=\u524a\u9664\u3057\u3066\u3044\u307e\u3059... label.description=\u8aac\u660e @@ -430,28 +455,32 @@ label.destination.zone=\u30b3\u30d4\u30fc\u5148\u30be\u30fc\u30f3 label.destroy.router=\u30eb\u30fc\u30bf\u30fc\u306e\u7834\u68c4 label.destroy=\u7834\u68c4 label.detaching.disk=\u30c7\u30a3\u30b9\u30af\u3092\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u3044\u307e\u3059 -label.details=\u8a73\u7d30 +label.details=\u8a73\u7d30 label.device.id=\u30c7\u30d0\u30a4\u30b9 ID label.devices=\u30c7\u30d0\u30a4\u30b9 -label.dhcp=DHCP label.DHCP.server.type=DHCP \u30b5\u30fc\u30d0\u30fc\u306e\u7a2e\u985e -label.direct.ips=\u76f4\u63a5 IP \u30a2\u30c9\u30ec\u30b9 -label.disabled=\u7121\u52b9 +label.dhcp=DHCP +label.direct.ips=\u5171\u6709\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e IP \u30a2\u30c9\u30ec\u30b9 label.disable.provider=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u7121\u52b9\u5316 label.disable.vpn=VPN \u306e\u7121\u52b9\u5316 +label.disabled=\u7121\u52b9 label.disabling.vpn.access=VPN \u30a2\u30af\u30bb\u30b9\u3092\u7121\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 label.disk.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e\u30c7\u30a3\u30b9\u30af label.disk.offering=\u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 +label.disk.read.bytes=\u30c7\u30a3\u30b9\u30af\u8aad\u307f\u53d6\u308a (\u30d0\u30a4\u30c8) +label.disk.read.io=\u30c7\u30a3\u30b9\u30af\u8aad\u307f\u53d6\u308a (IO) label.disk.size.gb=\u30c7\u30a3\u30b9\u30af \u30b5\u30a4\u30ba (GB \u5358\u4f4d) label.disk.size=\u30c7\u30a3\u30b9\u30af \u30b5\u30a4\u30ba label.disk.total=\u30c7\u30a3\u30b9\u30af\u5408\u8a08 label.disk.volume=\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0 +label.disk.write.bytes=\u30c7\u30a3\u30b9\u30af\u66f8\u304d\u8fbc\u307f (\u30d0\u30a4\u30c8) +label.disk.write.io=\u30c7\u30a3\u30b9\u30af\u66f8\u304d\u8fbc\u307f (IO) label.display.name=\u8868\u793a\u540d label.display.text=\u8868\u793a\u30c6\u30ad\u30b9\u30c8 label.dns.1=DNS 1 label.dns.2=DNS 2 -label.dns=DNS label.DNS.domain.for.guest.networks=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e DNS \u30c9\u30e1\u30a4\u30f3 +label.dns=DNS label.domain.admin=\u30c9\u30e1\u30a4\u30f3\u7ba1\u7406\u8005 label.domain.id=\u30c9\u30e1\u30a4\u30f3 ID label.domain.name=\u30c9\u30e1\u30a4\u30f3\u540d @@ -462,41 +491,44 @@ label.done=\u5b8c\u4e86 label.double.quotes.are.not.allowed=\u4e8c\u91cd\u5f15\u7528\u7b26\u306f\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093 label.download.progress=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u306e\u9032\u6357\u72b6\u6cc1 label.drag.new.position=\u65b0\u3057\u3044\u4f4d\u7f6e\u306b\u30c9\u30e9\u30c3\u30b0 +label.edit.affinity.group=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u7de8\u96c6 label.edit.lb.rule=\u8ca0\u8377\u5206\u6563\u898f\u5247\u306e\u7de8\u96c6 label.edit.network.details=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8a73\u7d30\u306e\u7de8\u96c6 label.edit.project.details=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u8a73\u7d30\u306e\u7de8\u96c6 label.edit.tags=\u30bf\u30b0\u306e\u7de8\u96c6 label.edit.traffic.type=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e\u306e\u7de8\u96c6 -label.edit=\u7de8\u96c6 label.edit.vpc=VPC \u306e\u7de8\u96c6 -label.egress.rules=\u9001\u4fe1\u30eb\u30fc\u30eb +label.edit=\u7de8\u96c6 label.egress.rule=\u9001\u4fe1\u898f\u5247 +label.egress.rules=\u9001\u4fe1\u898f\u5247 label.elastic.IP=\u30a8\u30e9\u30b9\u30c6\u30a3\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 label.elastic.LB=\u30a8\u30e9\u30b9\u30c6\u30a3\u30c3\u30af\u8ca0\u8377\u5206\u6563 label.elastic=\u30a8\u30e9\u30b9\u30c6\u30a3\u30c3\u30af label.email=\u96fb\u5b50\u30e1\u30fc\u30eb label.enable.provider=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u6709\u52b9\u5316 -label.enable.s3=S3\u57fa\u76e4\u30bb\u30ab\u30f3\u30c0\u30ea\u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u6709\u52b9\u5316 +label.enable.s3=S3 \u30d9\u30fc\u30b9\u306e\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u6709\u52b9\u5316 label.enable.swift=Swift \u306e\u6709\u52b9\u5316 label.enable.vpn=VPN \u306e\u6709\u52b9\u5316 label.enabling.vpn.access=VPN \u30a2\u30af\u30bb\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 label.enabling.vpn=VPN \u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 label.end.IP=\u7d42\u4e86 IP \u30a2\u30c9\u30ec\u30b9 -label.endpoint.or.operation=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u307e\u305f\u306f\u64cd\u4f5c -label.endpoint=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8 label.end.port=\u7d42\u4e86\u30dd\u30fc\u30c8 label.end.reserved.system.IP=\u4e88\u7d04\u6e08\u307f\u7d42\u4e86\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9 label.end.vlan=\u7d42\u4e86 VLAN +label.endpoint.or.operation=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u307e\u305f\u306f\u64cd\u4f5c +label.endpoint=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8 label.enter.token=\u30c8\u30fc\u30af\u30f3\u306e\u5165\u529b label.error.code=\u30a8\u30e9\u30fc \u30b3\u30fc\u30c9 label.error=\u30a8\u30e9\u30fc label.ESP.encryption=ESP \u6697\u53f7\u5316 label.ESP.hash=ESP \u30cf\u30c3\u30b7\u30e5 +label.ESP.lifetime=ESP \u6709\u52b9\u671f\u9593 (\u79d2) label.ESP.policy=ESP \u30dd\u30ea\u30b7\u30fc label.esx.host=ESX/ESXi \u30db\u30b9\u30c8 label.example=\u4f8b +label.external.link=\u5916\u90e8\u30ea\u30f3\u30af label.f5=F5 -label.failed=\u5931\u6557 +label.failed=\u5931\u6557 label.featured=\u304a\u3059\u3059\u3081 label.fetch.latest=\u6700\u65b0\u60c5\u5831\u306e\u53d6\u5f97 label.filterBy=\u30d5\u30a3\u30eb\u30bf\u30fc @@ -533,18 +565,19 @@ label.hints=\u30d2\u30f3\u30c8 label.host.alerts=\u30db\u30b9\u30c8 \u30a2\u30e9\u30fc\u30c8 label.host.MAC=\u30db\u30b9\u30c8\u306e MAC label.host.name=\u30db\u30b9\u30c8\u540d -label.hosts=\u30db\u30b9\u30c8 label.host.tags=\u30db\u30b9\u30c8 \u30bf\u30b0 label.host=\u30db\u30b9\u30c8 +label.hosts=\u30db\u30b9\u30c8 label.hourly=\u6bce\u6642 label.hypervisor.capabilities=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u306e\u6a5f\u80fd label.hypervisor.type=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u306e\u7a2e\u985e -label.hypervisor=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc label.hypervisor.version=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u306e\u30d0\u30fc\u30b8\u30e7\u30f3 +label.hypervisor=\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc label.id=ID label.IKE.DH=IKE DH label.IKE.encryption=IKE \u6697\u53f7\u5316 label.IKE.hash=IKE \u30cf\u30c3\u30b7\u30e5 +label.IKE.lifetime=IKE \u6709\u52b9\u671f\u9593 (\u79d2) label.IKE.policy=IKE \u30dd\u30ea\u30b7\u30fc label.info=\u60c5\u5831 label.ingress.rule=\u53d7\u4fe1\u898f\u5247 @@ -557,68 +590,75 @@ label.installWizard.addPodIntro.subtitle=\u30dd\u30c3\u30c9\u306b\u3064\u3044\u3 label.installWizard.addPodIntro.title=\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u307e\u3057\u3087\u3046 label.installWizard.addPrimaryStorageIntro.subtitle=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u3064\u3044\u3066 label.installWizard.addPrimaryStorageIntro.title=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3057\u3087\u3046 -label.installWizard.addSecondaryStorageIntro.subtitle=\u30bb\u30ab\u30f3\u30c0\u30ea\u30fc\u30b9\u30c8\u30ec\u30fc\u30b8\u3068\u306f\uff1f +label.installWizard.addSecondaryStorageIntro.subtitle=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u3064\u3044\u3066 label.installWizard.addSecondaryStorageIntro.title=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3057\u3087\u3046 +label.installWizard.addZone.title=\u30be\u30fc\u30f3\u306e\u8ffd\u52a0 label.installWizard.addZoneIntro.subtitle=\u30be\u30fc\u30f3\u306b\u3064\u3044\u3066 label.installWizard.addZoneIntro.title=\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3057\u307e\u3057\u3087\u3046 -label.installWizard.addZone.title=\u30be\u30fc\u30f3\u306e\u8ffd\u52a0 label.installWizard.click.launch=[\u8d77\u52d5] \u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -label.installWizard.subtitle=\u3053\u306e\u30ac\u30a4\u30c9 \u30c4\u30a2\u30fc\u306f CloudStack™ \u74b0\u5883\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306b\u5f79\u7acb\u3061\u307e\u3059 -label.installWizard.title=CloudStack™ \u3078\u3088\u3046\u3053\u305d +label.installWizard.subtitle=\u3053\u306e\u30ac\u30a4\u30c9 \u30c4\u30a2\u30fc\u306f CloudStack&\#8482; \u74b0\u5883\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306b\u5f79\u7acb\u3061\u307e\u3059 +label.installWizard.title=CloudStack&\#8482 \u3078\u3088\u3046\u3053\u305d label.instance.limits=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u5236\u9650 label.instance.name=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u540d -label.instances=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 label.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 +label.instances=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 label.internal.dns.1=\u5185\u90e8 DNS 1 label.internal.dns.2=\u5185\u90e8 DNS 2 label.internal.name=\u5185\u90e8\u540d label.interval.type=\u9593\u9694\u306e\u7a2e\u985e -label.introduction.to.cloudstack=CloudStack™ \u306e\u7d39\u4ecb +label.introduction.to.cloudstack=CloudStack&\#8482; \u306e\u7d39\u4ecb label.invalid.integer=\u7121\u52b9\u306a\u6574\u6570 label.invalid.number=\u7121\u52b9\u306a\u6570 label.invitations=\u62db\u5f85\u72b6 -label.invited.accounts=\u62db\u5f85\u6e08\u307f\u30a2\u30ab\u30a6\u30f3\u30c8 label.invite.to=\u62db\u5f85\u3059\u308b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8: label.invite=\u62db\u5f85 +label.invited.accounts=\u62db\u5f85\u6e08\u307f\u30a2\u30ab\u30a6\u30f3\u30c8 label.ip.address=IP \u30a2\u30c9\u30ec\u30b9 -label.ipaddress=IP \u30a2\u30c9\u30ec\u30b9 label.ip.allocations=IP \u30a2\u30c9\u30ec\u30b9\u306e\u5272\u308a\u5f53\u3066 -label.ip=IP label.ip.limits=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u306e\u5236\u9650 label.ip.or.fqdn=IP \u30a2\u30c9\u30ec\u30b9\u307e\u305f\u306f FQDN label.ip.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 label.ip.ranges=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 -label.IPsec.preshared.key=IPsec \u4e8b\u524d\u5171\u6709\u30ad\u30fc +label.ip=IP +label.ipaddress=IP \u30a2\u30c9\u30ec\u30b9 label.ips=IP +label.IPsec.preshared.key=IPsec \u4e8b\u524d\u5171\u6709\u30ad\u30fc +label.is.default=\u30c7\u30d5\u30a9\u30eb\u30c8 +label.is.redundant.router=\u5197\u9577 +label.is.shared=\u5171\u6709 +label.is.system=\u30b7\u30b9\u30c6\u30e0 label.iscsi=iSCSI -label.is.default=\u30c7\u30d5\u30a9\u30eb\u30c8 label.iso.boot=ISO \u8d77\u52d5 -label.iso=ISO +label.iso=ISO label.isolated.networks=\u5206\u96e2\u3055\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.isolation.method=\u5206\u96e2\u65b9\u6cd5 label.isolation.mode=\u5206\u96e2\u30e2\u30fc\u30c9 -label.isolation.uri=Isolation URI -label.is.redundant.router=\u5197\u9577 -label.is.shared=\u5171\u6709 -label.is.system=\u30b7\u30b9\u30c6\u30e0 +label.isolation.uri=\u5206\u96e2 URI label.item.listing=\u9805\u76ee\u4e00\u89a7 label.keep=\u7dad\u6301 -label.keyboard.type=\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u7a2e\u985e label.key=\u30ad\u30fc +label.keyboard.type=\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u7a2e\u985e label.kvm.traffic.label=KVM \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u30e9\u30d9\u30eb label.label=\u30e9\u30d9\u30eb -label.lang.brportugese=Brazilian Portugese +label.lang.arabic=\u30a2\u30e9\u30d3\u30a2\u8a9e +label.lang.brportugese=\u30dd\u30eb\u30c8\u30ac\u30eb\u8a9e (\u30d6\u30e9\u30b8\u30eb) +label.lang.catalan=\u30ab\u30bf\u30eb\u30cb\u30a2\u8a9e label.lang.chinese=\u7c21\u4f53\u5b57\u4e2d\u56fd\u8a9e label.lang.english=\u82f1\u8a9e -label.lang.french=French +label.lang.french=\u30d5\u30e9\u30f3\u30b9\u8a9e +label.lang.german=\u30c9\u30a4\u30c4\u8a9e +label.lang.italian=\u30a4\u30bf\u30ea\u30a2\u8a9e label.lang.japanese=\u65e5\u672c\u8a9e -label.lang.russian=Russian +label.lang.korean=\u97d3\u56fd\u8a9e +label.lang.norwegian=\u30ce\u30eb\u30a6\u30a7\u30fc\u8a9e +label.lang.russian=\u30ed\u30b7\u30a2\u8a9e label.lang.spanish=\u30b9\u30da\u30a4\u30f3\u8a9e label.last.disconnected=\u6700\u7d42\u5207\u65ad\u65e5\u6642 label.last.name=\u59d3 label.latest.events=\u6700\u65b0\u30a4\u30d9\u30f3\u30c8 -label.launch=\u8d77\u52d5 label.launch.vm=VM \u306e\u8d77\u52d5 +label.launch.zone=\u30be\u30fc\u30f3\u306e\u8d77\u52d5 +label.launch=\u8d77\u52d5 label.LB.isolation=\u8ca0\u8377\u5206\u6563\u5206\u96e2 label.least.connections=\u6700\u5c0f\u63a5\u7d9a label.level=\u30ec\u30d9\u30eb @@ -632,28 +672,33 @@ label.local.storage=\u30ed\u30fc\u30ab\u30eb \u30b9\u30c8\u30ec\u30fc\u30b8 label.local=\u30ed\u30fc\u30ab\u30eb label.login=\u30ed\u30b0\u30aa\u30f3 label.logout=\u30ed\u30b0\u30aa\u30d5 -label.lun=LUN label.LUN.number=LUN \u756a\u53f7 +label.lun=LUN label.make.project.owner=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u6240\u6709\u8005\u5316 -label.management.ips=\u7ba1\u7406 IP \u30a2\u30c9\u30ec\u30b9 -label.management=\u7ba1\u7406 label.manage.resources=\u30ea\u30bd\u30fc\u30b9\u306e\u7ba1\u7406 label.manage=\u7ba1\u7406 +label.management.ips=\u7ba1\u7406 IP \u30a2\u30c9\u30ec\u30b9 +label.management=\u7ba1\u7406 +label.max.cpus=\u6700\u5927 CPU \u30b3\u30a2\u6570 label.max.guest.limit=\u6700\u5927\u30b2\u30b9\u30c8\u5236\u9650 -label.maximum=\u6700\u5927 +label.max.memory=\u6700\u5927\u30e1\u30e2\u30ea (MiB) label.max.networks=\u6700\u5927\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u6570 +label.max.primary.storage=\u6700\u5927\u30d7\u30e9\u30a4\u30de\u30ea (GiB) label.max.public.ips=\u6700\u5927\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u6570 +label.max.secondary.storage=\u6700\u5927\u30bb\u30ab\u30f3\u30c0\u30ea (GiB) label.max.snapshots=\u6700\u5927\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u6570 label.max.templates=\u6700\u5927\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u6570 label.max.vms=\u6700\u5927\u30e6\u30fc\u30b6\u30fc VM \u6570 label.max.volumes=\u6700\u5927\u30dc\u30ea\u30e5\u30fc\u30e0\u6570 -label.max.vpcs=Max. VPCs +label.max.vpcs=\u6700\u5927 VPC \u6570 +label.maximum=\u6700\u5927 label.may.continue=\u7d9a\u884c\u3067\u304d\u307e\u3059\u3002 label.memory.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e\u30e1\u30e2\u30ea +label.memory.limits=\u30e1\u30e2\u30ea\u5236\u9650 (MiB) label.memory.mb=\u30e1\u30e2\u30ea (MB) label.memory.total=\u30e1\u30e2\u30ea\u5408\u8a08 -label.memory=\u30e1\u30e2\u30ea label.memory.used=\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf +label.memory=\u30e1\u30e2\u30ea label.menu.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8 label.menu.alerts=\u30a2\u30e9\u30fc\u30c8 label.menu.all.accounts=\u3059\u3079\u3066\u306e\u30a2\u30ab\u30a6\u30f3\u30c8 @@ -680,6 +725,7 @@ label.menu.my.templates=\u30de\u30a4 \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 label.menu.network.offerings=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.menu.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.menu.physical.resources=\u7269\u7406\u30ea\u30bd\u30fc\u30b9 +label.menu.regions=\u9818\u57df label.menu.running.instances=\u5b9f\u884c\u4e2d\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 label.menu.security.groups=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.menu.service.offerings=\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 @@ -687,8 +733,8 @@ label.menu.snapshots=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 label.menu.stopped.instances=\u505c\u6b62\u3055\u308c\u305f\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 label.menu.storage=\u30b9\u30c8\u30ec\u30fc\u30b8 label.menu.system.service.offerings=\u30b7\u30b9\u30c6\u30e0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 -label.menu.system=\u30b7\u30b9\u30c6\u30e0 label.menu.system.vms=\u30b7\u30b9\u30c6\u30e0 VM +label.menu.system=\u30b7\u30b9\u30c6\u30e0 label.menu.templates=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 label.menu.virtual.appliances=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9 label.menu.virtual.resources=\u4eee\u60f3\u30ea\u30bd\u30fc\u30b9 @@ -718,16 +764,15 @@ label.name=\u540d\u524d label.nat.port.range=NAT \u30dd\u30fc\u30c8\u306e\u7bc4\u56f2 label.netmask=\u30cd\u30c3\u30c8\u30de\u30b9\u30af label.netScaler=NetScaler -label.network.ACLs=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL label.network.ACL.total=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL \u5408\u8a08 label.network.ACL=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL +label.network.ACLs=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ACL label.network.desc=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8aac\u660e label.network.device.type=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c7\u30d0\u30a4\u30b9\u306e\u7a2e\u985e label.network.device=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c7\u30d0\u30a4\u30b9 label.network.domain.text=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c9\u30e1\u30a4\u30f3 label.network.domain=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c9\u30e1\u30a4\u30f3 label.network.id=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ID -label.networking.and.security=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 label.network.label.display.for.blank.value=\u30c7\u30d5\u30a9\u30eb\u30c8 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3092\u4f7f\u7528 label.network.name=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u540d label.network.offering.display.text=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u8868\u793a\u30c6\u30ad\u30b9\u30c8 @@ -738,23 +783,24 @@ label.network.rate.megabytes=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u901f\u5ea6 (M label.network.rate=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u901f\u5ea6 label.network.read=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8aad\u307f\u53d6\u308a label.network.service.providers=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30b5\u30fc\u30d3\u30b9 \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc -label.networks=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.network.type=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u7a2e\u985e -label.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.network.write=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u66f8\u304d\u8fbc\u307f +label.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af +label.networking.and.security=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 +label.networks=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.new.password=\u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9 label.new.project=\u65b0\u3057\u3044\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 -label.new=\u65b0\u898f label.new.vm=\u65b0\u3057\u3044 VM +label.new=\u65b0\u898f label.next=\u6b21\u3078 label.nexusVswitch=Nexus 1000V -label.nfs=NFS label.nfs.server=NFS \u30b5\u30fc\u30d0\u30fc label.nfs.storage=NFS \u30b9\u30c8\u30ec\u30fc\u30b8 +label.nfs=NFS label.nic.adapter.type=NIC \u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u7a2e\u985e -label.nicira.controller.address=\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u30a2\u30c9\u30ec\u30b9 -label.nicira.l3gatewayserviceuuid=L3 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30b5\u30fc\u30d3\u30b9UUID -label.nicira.transportzoneuuid=Transport Zone Uuid +label.nicira.controller.address=\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc \u30a2\u30c9\u30ec\u30b9 +label.nicira.l3gatewayserviceuuid=L3 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 \u30b5\u30fc\u30d3\u30b9\u306e UUID +label.nicira.transportzoneuuid=\u30c8\u30e9\u30f3\u30b9\u30dd\u30fc\u30c8 \u30be\u30fc\u30f3\u306e UUID label.nics=NIC label.no.actions=\u5b9f\u884c\u3067\u304d\u308b\u64cd\u4f5c\u306f\u3042\u308a\u307e\u305b\u3093 label.no.alerts=\u6700\u8fd1\u306e\u30a2\u30e9\u30fc\u30c8\u306f\u3042\u308a\u307e\u305b\u3093 @@ -762,19 +808,19 @@ label.no.data=\u8868\u793a\u3059\u308b\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e label.no.errors=\u6700\u8fd1\u306e\u30a8\u30e9\u30fc\u306f\u3042\u308a\u307e\u305b\u3093 label.no.isos=\u4f7f\u7528\u3067\u304d\u308b ISO \u306f\u3042\u308a\u307e\u305b\u3093 label.no.items=\u4f7f\u7528\u3067\u304d\u308b\u9805\u76ee\u306f\u3042\u308a\u307e\u305b\u3093 -label.none=\u306a\u3057 label.no.security.groups=\u4f7f\u7528\u3067\u304d\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306f\u3042\u308a\u307e\u305b\u3093 -label.not.found=\u898b\u3064\u304b\u308a\u307e\u305b\u3093 label.no.thanks=\u8a2d\u5b9a\u3057\u306a\u3044 -label.notifications=\u901a\u77e5 label.no=\u3044\u3044\u3048 +label.none=\u306a\u3057 +label.not.found=\u898b\u3064\u304b\u308a\u307e\u305b\u3093 +label.notifications=\u901a\u77e5 +label.num.cpu.cores=CPU \u30b3\u30a2\u6570 label.number.of.clusters=\u30af\u30e9\u30b9\u30bf\u30fc\u6570 label.number.of.hosts=\u30db\u30b9\u30c8\u6570 label.number.of.pods=\u30dd\u30c3\u30c9\u6570 label.number.of.system.vms=\u30b7\u30b9\u30c6\u30e0 VM \u6570 label.number.of.virtual.routers=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u6570 label.number.of.zones=\u30be\u30fc\u30f3\u6570 -label.num.cpu.cores=CPU \u30b3\u30a2\u6570 label.numretries=\u518d\u8a66\u884c\u56de\u6570 label.ocfs2=OCFS2 label.offer.ha=\u9ad8\u53ef\u7528\u6027\u306e\u63d0\u4f9b @@ -792,51 +838,56 @@ label.password=\u30d1\u30b9\u30ef\u30fc\u30c9 label.path=\u30d1\u30b9 label.perfect.forward.secrecy=Perfect Forward Secrecy label.physical.network.ID=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af ID +label.physical.network=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.PING.CIFS.password=PING CIFS \u30d1\u30b9\u30ef\u30fc\u30c9 label.PING.CIFS.username=PING CIFS \u30e6\u30fc\u30b6\u30fc\u540d label.PING.dir=PING \u30c7\u30a3\u30ec\u30af\u30c8\u30ea label.PING.storage.IP=PING \u5bfe\u8c61\u306e\u30b9\u30c8\u30ec\u30fc\u30b8 IP \u30a2\u30c9\u30ec\u30b9 label.please.specify.netscaler.info=Netscaler \u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044 -label.please.wait=\u304a\u5f85\u3061\u304f\u3060\u3055\u3044 +label.please.wait=\u304a\u5f85\u3061\u304f\u3060\u3055\u3044 +label.plugin.details=\u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u8a73\u7d30 +label.plugins=\u30d7\u30e9\u30b0\u30a4\u30f3 label.pod.name=\u30dd\u30c3\u30c9\u540d -label.pods=\u30dd\u30c3\u30c9 label.pod=\u30dd\u30c3\u30c9 +label.pods=\u30dd\u30c3\u30c9 label.port.forwarding.policies=\u30dd\u30fc\u30c8\u8ee2\u9001\u30dd\u30ea\u30b7\u30fc label.port.forwarding=\u30dd\u30fc\u30c8\u8ee2\u9001 label.port.range=\u30dd\u30fc\u30c8\u306e\u7bc4\u56f2 label.PreSetup=PreSetup -label.previous=\u623b\u308b label.prev=\u623b\u308b +label.previous=\u623b\u308b label.primary.allocated=\u5272\u308a\u5f53\u3066\u6e08\u307f\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 label.primary.network=\u30d7\u30e9\u30a4\u30de\u30ea \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.primary.storage.count=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30d7\u30fc\u30eb +label.primary.storage.limits=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u5236\u9650 (GiB) label.primary.storage=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 label.primary.used=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u4f7f\u7528\u91cf label.private.Gateway=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.private.interface=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9 label.private.ip.range=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2 -label.private.ips=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9 label.private.ip=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9 -label.privatekey=PKC#8 \u79d8\u5bc6\u30ad\u30fc +label.private.ips=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9 label.private.network=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.private.port=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30dd\u30fc\u30c8 label.private.zone=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30be\u30fc\u30f3 +label.privatekey=PKCS\#8 \u79d8\u5bc6\u30ad\u30fc label.project.dashboard=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9 label.project.id=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 ID label.project.invite=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u62db\u5f85 label.project.name=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u540d -label.projects=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 -label.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 label.project.view=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30d3\u30e5\u30fc +label.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 +label.projects=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 label.protocol=\u30d7\u30ed\u30c8\u30b3\u30eb label.providers=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc label.public.interface=\u30d1\u30d6\u30ea\u30c3\u30af \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9 -label.public.ips=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 label.public.ip=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 +label.public.ips=\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9 label.public.network=\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.public.port=\u30d1\u30d6\u30ea\u30c3\u30af \u30dd\u30fc\u30c8 -label.public=\u30d1\u30d6\u30ea\u30c3\u30af +label.public.traffic=\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af label.public.zone=\u30d1\u30d6\u30ea\u30c3\u30af \u30be\u30fc\u30f3 +label.public=\u30d1\u30d6\u30ea\u30c3\u30af label.purpose=\u76ee\u7684 label.Pxe.server.type=PXE \u30b5\u30fc\u30d0\u30fc\u306e\u7a2e\u985e label.quickview=\u30af\u30a4\u30c3\u30af\u30d3\u30e5\u30fc @@ -846,6 +897,7 @@ label.redundant.router.capability=\u5197\u9577\u30eb\u30fc\u30bf\u30fc\u6a5f\u80 label.redundant.router=\u5197\u9577\u30eb\u30fc\u30bf\u30fc label.redundant.state=\u5197\u9577\u72b6\u614b label.refresh=\u66f4\u65b0 +label.region=\u9818\u57df label.related=\u95a2\u9023 label.remind.later=\u30a2\u30e9\u30fc\u30e0\u3092\u8868\u793a\u3059\u308b label.remove.ACL=ACL \u306e\u524a\u9664 @@ -854,27 +906,32 @@ label.remove.from.load.balancer=\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u304b\u3089 label.remove.ingress.rule=\u53d7\u4fe1\u898f\u5247\u306e\u524a\u9664 label.remove.ip.range=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u524a\u9664 label.remove.pf=\u30dd\u30fc\u30c8\u8ee2\u9001\u898f\u5247\u306e\u524a\u9664 +label.remove.project.account=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u524a\u9664 +label.remove.region=\u9818\u57df\u306e\u524a\u9664 label.remove.rule=\u898f\u5247\u306e\u524a\u9664 label.remove.static.nat.rule=\u9759\u7684 NAT \u898f\u5247\u306e\u524a\u9664 label.remove.static.route=\u9759\u7684\u30eb\u30fc\u30c8\u306e\u524a\u9664 label.remove.tier=\u968e\u5c64\u306e\u524a\u9664 label.remove.vm.from.lb=\u8ca0\u8377\u5206\u6563\u898f\u5247\u304b\u3089\u306e VM \u306e\u524a\u9664 label.remove.vpc=VPC \u306e\u524a\u9664 -label.removing=\u524a\u9664\u3057\u3066\u3044\u307e\u3059 label.removing.user=\u30e6\u30fc\u30b6\u30fc\u3092\u524a\u9664\u3057\u3066\u3044\u307e\u3059 +label.removing=\u524a\u9664\u3057\u3066\u3044\u307e\u3059 label.required=\u5fc5\u9808\u3067\u3059 label.reserved.system.gateway=\u4e88\u7d04\u6e08\u307f\u30b7\u30b9\u30c6\u30e0 \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.reserved.system.ip=\u4e88\u7d04\u6e08\u307f\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9 label.reserved.system.netmask=\u4e88\u7d04\u6e08\u307f\u30b7\u30b9\u30c6\u30e0 \u30cd\u30c3\u30c8\u30de\u30b9\u30af label.reset.VPN.connection=VPN \u63a5\u7d9a\u306e\u30ea\u30bb\u30c3\u30c8 +label.resize.new.offering.id=\u65b0\u3057\u3044\u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 +label.resize.new.size=\u65b0\u3057\u3044\u30b5\u30a4\u30ba (GB) +label.resize.shrink.ok=\u7e2e\u5c0f\u53ef\u80fd label.resource.limits=\u30ea\u30bd\u30fc\u30b9\u5236\u9650 label.resource.state=\u30ea\u30bd\u30fc\u30b9\u306e\u72b6\u614b -label.resources=\u30ea\u30bd\u30fc\u30b9 label.resource=\u30ea\u30bd\u30fc\u30b9 +label.resources=\u30ea\u30bd\u30fc\u30b9 label.restart.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u518d\u8d77\u52d5 label.restart.required=\u518d\u8d77\u52d5\u304c\u5fc5\u8981 label.restart.vpc=VPC \u306e\u518d\u8d77\u52d5 -label.restore=\u30ea\u30b9\u30c8\u30a2 +label.restore=\u5fa9\u5143 label.review=\u78ba\u8a8d label.revoke.project.invite=\u62db\u5f85\u306e\u53d6\u308a\u6d88\u3057 label.role=\u5f79\u5272 @@ -882,15 +939,15 @@ label.root.disk.controller=\u30eb\u30fc\u30c8 \u30c7\u30a3\u30b9\u30af \u30b3\u3 label.root.disk.offering=\u30eb\u30fc\u30c8 \u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.round.robin=\u30e9\u30a6\u30f3\u30c9\u30ed\u30d3\u30f3 label.rules=\u898f\u5247 -label.running.vms=\u5b9f\u884c\u4e2d\u306e VM -label.s3.access_key=\u30a2\u30af\u30bb\u30b9\u30ad\u30fc +label.running.vms=\u5b9f\u884c\u4e2d\u306e VM +label.s3.access_key=\u30a2\u30af\u30bb\u30b9 \u30ad\u30fc label.s3.bucket=\u30d0\u30b1\u30c3\u30c8 -label.s3.connection_timeout=\u30b3\u30cd\u30af\u30b7\u30e7\u30f3\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 +label.s3.connection_timeout=\u63a5\u7d9a\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 label.s3.endpoint=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8 -label.s3.max_error_retry=\u30a8\u30e9\u30fc\u6642\u306e\u6700\u5927\u30ea\u30c8\u30e9\u30a4\u6570 -label.s3.secret_key=\u79d8\u5bc6\u9375 -label.s3.socket_timeout=\u30bd\u30b1\u30c3\u30c8\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 -label.s3.use_https=HTTPS\u306e\u4f7f\u7528 +label.s3.max_error_retry=\u6700\u5927\u30a8\u30e9\u30fc\u518d\u8a66\u884c\u6570 +label.s3.secret_key=\u79d8\u5bc6\u30ad\u30fc +label.s3.socket_timeout=\u30bd\u30b1\u30c3\u30c8 \u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 +label.s3.use_https=HTTPS \u3092\u4f7f\u7528 label.saturday=\u571f\u66dc\u65e5 label.save.and.continue=\u4fdd\u5b58\u3057\u3066\u7d9a\u884c label.save=\u4fdd\u5b58 @@ -898,14 +955,16 @@ label.saving.processing=\u4fdd\u5b58\u3057\u3066\u3044\u307e\u3059... label.scope=\u30b9\u30b3\u30fc\u30d7 label.search=\u691c\u7d22 label.secondary.storage.count=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30d7\u30fc\u30eb -label.secondary.storage=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 +label.secondary.storage.limits=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u5236\u9650 (GiB) label.secondary.storage.vm=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 VM +label.secondary.storage=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 label.secondary.used=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u4f7f\u7528\u91cf -label.secret.key=\u79d8\u5bc6\u9375 +label.secret.key=\u79d8\u5bc6\u30ad\u30fc label.security.group.name=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u540d +label.security.group=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 label.security.groups.enabled=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u6709\u52b9 label.security.groups=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 -label.security.group=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 +label.select-view=\u30d3\u30e5\u30fc\u306e\u9078\u629e label.select.a.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u9078\u629e label.select.a.zone=\u30be\u30fc\u30f3\u306e\u9078\u629e label.select.instance.to.attach.volume.to=\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30a2\u30bf\u30c3\u30c1\u3059\u308b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 @@ -914,20 +973,19 @@ label.select.iso.or.template=ISO \u307e\u305f\u306f\u30c6\u30f3\u30d7\u30ec\u30f label.select.offering=\u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u9078\u629e label.select.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u9078\u629e label.select.tier=\u968e\u5c64\u306e\u9078\u629e -label.select=\u9078\u629e -label.select-view=\u30d3\u30e5\u30fc\u306e\u9078\u629e label.select.vm.for.static.nat=\u9759\u7684 NAT \u7528 VM \u306e\u9078\u629e +label.select=\u9078\u629e label.sent=\u9001\u4fe1\u6e08\u307f label.server=\u30b5\u30fc\u30d0\u30fc label.service.capabilities=\u30b5\u30fc\u30d3\u30b9\u306e\u6a5f\u80fd label.service.offering=\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.session.expired=\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u307e\u3057\u305f -label.setup.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 -label.setup=\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 label.set.up.zone.type=\u30be\u30fc\u30f3\u306e\u7a2e\u985e\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 +label.setup.network=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 label.setup.zone=\u30be\u30fc\u30f3\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 -label.SharedMountPoint=SharedMountPoint +label.setup=\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 label.shared=\u5171\u6709 +label.SharedMountPoint=SharedMountPoint label.show.ingress.rule=\u53d7\u4fe1\u898f\u5247\u306e\u8868\u793a label.shutdown.provider=\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3 label.site.to.site.VPN=\u30b5\u30a4\u30c8\u9593 VPN @@ -935,10 +993,10 @@ label.size=\u30b5\u30a4\u30ba label.skip.guide=CloudStack \u3092\u4f7f\u7528\u3057\u305f\u3053\u3068\u304c\u3042\u308b\u306e\u3067\u3001\u3053\u306e\u30ac\u30a4\u30c9\u3092\u30b9\u30ad\u30c3\u30d7\u3059\u308b label.snapshot.limits=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u5236\u9650 label.snapshot.name=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u540d -label.snapshot.schedule=\u5b9a\u671f\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 label.snapshot.s=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 -label.snapshots=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 +label.snapshot.schedule=\u5b9a\u671f\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 label.snapshot=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 +label.snapshots=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 label.source.nat=\u9001\u4fe1\u5143 NAT label.source=\u9001\u4fe1\u5143 label.specify.IP.ranges=IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u6307\u5b9a @@ -952,19 +1010,19 @@ label.start.vlan=\u958b\u59cb VLAN label.state=\u72b6\u614b label.static.nat.enabled=\u9759\u7684 NAT \u6709\u52b9 label.static.nat.to=\u9759\u7684 NAT \u306e\u8a2d\u5b9a\u5148: -label.static.nat=\u9759\u7684 NAT label.static.nat.vm.details=\u9759\u7684 NAT VM \u306e\u8a73\u7d30 +label.static.nat=\u9759\u7684 NAT label.statistics=\u7d71\u8a08 label.status=\u72b6\u614b -label.step.1.title=\u624b\u9806 1. \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u9078\u629e +label.step.1.title=\u624b\u9806 1\: \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u9078\u629e label.step.1=\u624b\u9806 1 -label.step.2.title=\u624b\u9806 2. \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 +label.step.2.title=\u624b\u9806 2\: \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.step.2=\u624b\u9806 2 -label.step.3.title=\u624b\u9806 3. \u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u9078\u629e +label.step.3.title=\u624b\u9806 3\: \u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u9078\u629e label.step.3=\u624b\u9806 3 -label.step.4.title=\u624b\u9806 4. \u30cd\u30c3\u30c8\u30ef\u30fc\u30af +label.step.4.title=\u624b\u9806 4\: \u30cd\u30c3\u30c8\u30ef\u30fc\u30af label.step.4=\u624b\u9806 4 -label.step.5.title=\u624b\u9806 5. \u78ba\u8a8d +label.step.5.title=\u624b\u9806 5\: \u78ba\u8a8d label.step.5=\u624b\u9806 5 label.stickiness=\u6301\u7d9a\u6027 label.sticky.cookie-name=Cookie \u540d @@ -979,16 +1037,16 @@ label.sticky.postonly=\u30dd\u30b9\u30c8\u306e\u307f label.sticky.prefix=\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9 label.sticky.request-learn=\u30e9\u30fc\u30cb\u30f3\u30b0\u306e\u8981\u6c42 label.sticky.tablesize=\u30c6\u30fc\u30d6\u30eb \u30b5\u30a4\u30ba -label.stopped.vms=\u505c\u6b62\u4e2d\u306e VM label.stop=\u505c\u6b62 +label.stopped.vms=\u505c\u6b62\u4e2d\u306e VM label.storage.tags=\u30b9\u30c8\u30ec\u30fc\u30b8 \u30bf\u30b0 label.storage.traffic=\u30b9\u30c8\u30ec\u30fc\u30b8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af label.storage.type=\u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u7a2e\u985e label.storage=\u30b9\u30c8\u30ec\u30fc\u30b8 label.subdomain.access=\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3 \u30a2\u30af\u30bb\u30b9 -label.submitted.by=[\u9001\u4fe1\u30e6\u30fc\u30b6\u30fc: ] label.submit=\u9001\u4fe1 -label.succeeded=\u6210\u529f +label.submitted.by=[\u9001\u4fe1\u30e6\u30fc\u30b6\u30fc\: ] +label.succeeded=\u6210\u529f label.sunday=\u65e5\u66dc\u65e5 label.super.cidr.for.guest.networks=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30b9\u30fc\u30d1\u30fc CIDR label.supported.services=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u308b\u30b5\u30fc\u30d3\u30b9 @@ -997,9 +1055,9 @@ label.suspend.project=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4e00\u6642\u50 label.system.capacity=\u30b7\u30b9\u30c6\u30e0\u306e\u51e6\u7406\u80fd\u529b label.system.offering=\u30b7\u30b9\u30c6\u30e0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 label.system.service.offering=\u30b7\u30b9\u30c6\u30e0 \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0 -label.system.vms=\u30b7\u30b9\u30c6\u30e0 VM label.system.vm.type=\u30b7\u30b9\u30c6\u30e0 VM \u306e\u7a2e\u985e label.system.vm=\u30b7\u30b9\u30c6\u30e0 VM +label.system.vms=\u30b7\u30b9\u30c6\u30e0 VM label.system.wide.capacity=\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u306e\u51e6\u7406\u80fd\u529b label.tagged=\u30bf\u30b0\u3042\u308a label.tags=\u30bf\u30b0 @@ -1014,14 +1072,14 @@ label.theme.lightblue=\u30ab\u30b9\u30bf\u30e0 - \u30e9\u30a4\u30c8 \u30d6\u30eb label.thursday=\u6728\u66dc\u65e5 label.tier.details=\u968e\u5c64\u306e\u8a73\u7d30 label.tier=\u968e\u5c64 +label.time.zone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3 +label.time=\u6642\u523b label.timeout.in.second = \u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 (\u79d2) label.timeout=\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8 -label.time=\u6642\u523b -label.time.zone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3 label.timezone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3 label.token=\u30c8\u30fc\u30af\u30f3 -label.total.cpu=CPU \u5408\u8a08 label.total.CPU=CPU \u5408\u8a08 +label.total.cpu=CPU \u5408\u8a08 label.total.hosts=\u30db\u30b9\u30c8\u5408\u8a08 label.total.memory=\u30e1\u30e2\u30ea\u5408\u8a08 label.total.of.ip=IP \u30a2\u30c9\u30ec\u30b9\u5408\u8a08 @@ -1029,8 +1087,8 @@ label.total.of.vm=VM \u5408\u8a08 label.total.storage=\u30b9\u30c8\u30ec\u30fc\u30b8\u5408\u8a08 label.total.vms=VM \u5408\u8a08 label.traffic.label=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb -label.traffic.types=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e label.traffic.type=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e +label.traffic.types=\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e label.tuesday=\u706b\u66dc\u65e5 label.type.id=\u7a2e\u985e ID label.type=\u7a2e\u985e @@ -1038,17 +1096,18 @@ label.unavailable=\u4f7f\u7528\u4e0d\u80fd label.unlimited=\u7121\u5236\u9650 label.untagged=\u30bf\u30b0\u306a\u3057 label.update.project.resources=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30ea\u30bd\u30fc\u30b9\u306e\u66f4\u65b0 -label.update.ssl.cert= SSL \u8a3c\u660e\u66f8\u306e\u66f4\u65b0 -label.update.ssl= SSL \u8a3c\u660e\u66f8\u306e\u66f4\u65b0 +label.update.ssl.cert= SSL \u8a3c\u660e\u66f8 +label.update.ssl= SSL \u8a3c\u660e\u66f8 label.updating=\u66f4\u65b0\u3057\u3066\u3044\u307e\u3059 -label.upload=\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 label.upload.volume=\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 +label.upload=\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 label.url=URL label.usage.interface=\u4f7f\u7528\u72b6\u6cc1\u6e2c\u5b9a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9 +label.use.vm.ip=\u6b21\u306e VM IP \u30a2\u30c9\u30ec\u30b9\u3092\u4f7f\u7528\: label.used=\u4f7f\u7528\u4e2d +label.user=\u30e6\u30fc\u30b6\u30fc label.username=\u30e6\u30fc\u30b6\u30fc\u540d label.users=\u30e6\u30fc\u30b6\u30fc -label.user=\u30e6\u30fc\u30b6\u30fc label.value=\u5024 label.vcdcname=vCenter DC \u540d label.vcenter.cluster=vCenter \u30af\u30e9\u30b9\u30bf\u30fc @@ -1061,43 +1120,47 @@ label.vcipaddress=vCenter IP \u30a2\u30c9\u30ec\u30b9 label.version=\u30d0\u30fc\u30b8\u30e7\u30f3 label.view.all=\u3059\u3079\u3066\u8868\u793a label.view.console=\u30b3\u30f3\u30bd\u30fc\u30eb\u306e\u8868\u793a -label.viewing=\u8868\u793a\u9805\u76ee: label.view.more=\u8a73\u7d30\u8868\u793a label.view=\u8868\u793a - -label.virtual.appliances=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9 +label.viewing=\u8868\u793a\u9805\u76ee: label.virtual.appliance=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9 +label.virtual.appliances=\u4eee\u60f3\u30a2\u30d7\u30e9\u30a4\u30a2\u30f3\u30b9 label.virtual.machines=\u4eee\u60f3\u30de\u30b7\u30f3 label.virtual.network=\u4eee\u60f3\u30cd\u30c3\u30c8\u30ef\u30fc\u30af -label.virtual.routers=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc label.virtual.router=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc +label.virtual.routers=\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc label.vlan.id=VLAN ID label.vlan.range=VLAN \u306e\u7bc4\u56f2 label.vlan=VLAN label.vm.add=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u8ffd\u52a0 label.vm.destroy=\u7834\u68c4 label.vm.display.name=VM \u8868\u793a\u540d -label.VMFS.datastore=VMFS \u30c7\u30fc\u30bf\u30b9\u30c8\u30a2 -label.vmfs=VMFS label.vm.name=VM \u540d label.vm.reboot=\u518d\u8d77\u52d5 -label.VMs.in.tier=\u968e\u5c64\u5185\u306e VM -label.vmsnapshot.type=\u7a2e\u985e label.vm.start=\u8d77\u52d5 label.vm.state=VM \u306e\u72b6\u614b label.vm.stop=\u505c\u6b62 +label.VMFS.datastore=VMFS \u30c7\u30fc\u30bf\u30b9\u30c8\u30a2 +label.vmfs=VMFS +label.VMs.in.tier=\u968e\u5c64\u5185\u306e VM label.vms=VM +label.vmsnapshot.current=isCurrent +label.vmsnapshot.memory=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 \u30e1\u30e2\u30ea +label.vmsnapshot.parentname=\u89aa +label.vmsnapshot.type=\u7a2e\u985e +label.vmsnapshot=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 label.vmware.traffic.label=VMware \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u30e9\u30d9\u30eb label.volgroup=\u30dc\u30ea\u30e5\u30fc\u30e0 \u30b0\u30eb\u30fc\u30d7 label.volume.limits=\u30dc\u30ea\u30e5\u30fc\u30e0\u5236\u9650 label.volume.name=\u30dc\u30ea\u30e5\u30fc\u30e0\u540d -label.volumes=\u30dc\u30ea\u30e5\u30fc\u30e0 label.volume=\u30dc\u30ea\u30e5\u30fc\u30e0 +label.volumes=\u30dc\u30ea\u30e5\u30fc\u30e0 label.vpc.id=VPC ID label.VPC.router.details=VPC \u30eb\u30fc\u30bf\u30fc\u306e\u8a73\u7d30 label.vpc=VPC label.VPN.connection=VPN \u63a5\u7d9a -label.vpn.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.VPN.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 +label.vpn.customer.gateway=VPN \u30ab\u30b9\u30bf\u30de\u30fc \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.VPN.gateway=VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 label.vpn=VPN label.vsmctrlvlanid=\u30b3\u30f3\u30c8\u30ed\u30fc\u30eb VLAN ID @@ -1110,38 +1173,39 @@ label.wednesday=\u6c34\u66dc\u65e5 label.weekly=\u6bce\u9031 label.welcome.cloud.console=\u7ba1\u7406\u30b3\u30f3\u30bd\u30fc\u30eb\u3078\u3088\u3046\u3053\u305d label.welcome=\u3088\u3046\u3053\u305d -label.what.is.cloudstack=CloudStack™ \u306b\u3064\u3044\u3066 +label.what.is.cloudstack=CloudStack&\#8482; \u306b\u3064\u3044\u3066 label.xen.traffic.label=XenServer \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u30e9\u30d9\u30eb label.yes=\u306f\u3044 label.zone.details=\u30be\u30fc\u30f3\u306e\u8a73\u7d30 label.zone.id=\u30be\u30fc\u30f3 ID label.zone.name=\u30be\u30fc\u30f3\u540d -label.zone.step.1.title=\u624b\u9806 1. \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u9078\u629e -label.zone.step.2.title=\u624b\u9806 2. \u30be\u30fc\u30f3\u306e\u8ffd\u52a0 -label.zone.step.3.title=\u624b\u9806 3. \u30dd\u30c3\u30c9\u306e\u8ffd\u52a0 -label.zone.step.4.title=\u624b\u9806 4. IP \u30a2\u30c9\u30ec\u30b9\u7bc4\u56f2\u306e\u8ffd\u52a0 -label.zones=\u30be\u30fc\u30f3 +label.zone.step.1.title=\u624b\u9806 1\: \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u9078\u629e +label.zone.step.2.title=\u624b\u9806 2\: \u30be\u30fc\u30f3\u306e\u8ffd\u52a0 +label.zone.step.3.title=\u624b\u9806 3\: \u30dd\u30c3\u30c9\u306e\u8ffd\u52a0 +label.zone.step.4.title=\u624b\u9806 4\: IP \u30a2\u30c9\u30ec\u30b9\u7bc4\u56f2\u306e\u8ffd\u52a0 label.zone.type=\u30be\u30fc\u30f3\u306e\u7a2e\u985e -label.zone=\u30be\u30fc\u30f3 label.zone.wide=\u30be\u30fc\u30f3\u5168\u4f53 -label.zoneWizard.trafficType.guest=\u30b2\u30b9\u30c8: \u30a8\u30f3\u30c9\u30e6\u30fc\u30b6\u30fc\u4eee\u60f3\u30de\u30b7\u30f3\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af -label.zoneWizard.trafficType.public=\u30d1\u30d6\u30ea\u30c3\u30af: \u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u3068\u30af\u30e9\u30a6\u30c9\u5185\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af -label.zoneWizard.trafficType.storage=\u30b9\u30c8\u30ec\u30fc\u30b8: VM\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3068\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u3088\u3046\u306a\u3001\u30d7\u30e9\u30a4\u30de\u30ea\u3068\u30bb\u30ab\u30f3\u30c0\u30ea\u306e\u30b9\u30c8\u30ec\u30fc\u30b8\u30b5\u30fc\u30d0\u30fc\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3002 +label.zone=\u30be\u30fc\u30f3 +label.zones=\u30be\u30fc\u30f3 +label.zoneWizard.trafficType.guest=\u30b2\u30b9\u30c8\: \u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002 +label.zoneWizard.trafficType.management=\u7ba1\u7406\: \u30db\u30b9\u30c8\u3084 CloudStack \u30b7\u30b9\u30c6\u30e0 VM \u306a\u3069\u3001\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u3068\u901a\u4fe1\u3059\u308b CloudStack \u306e\u5185\u90e8\u30ea\u30bd\u30fc\u30b9\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002 +label.zoneWizard.trafficType.public=\u30d1\u30d6\u30ea\u30c3\u30af\: \u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u3068\u30af\u30e9\u30a6\u30c9\u5185\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002 +label.zoneWizard.trafficType.storage=\u30b9\u30c8\u30ec\u30fc\u30b8\: VM \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3084\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306a\u3069\u3001\u30d7\u30e9\u30a4\u30de\u30ea\u304a\u3088\u3073\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002 managed.state=\u7ba1\u7406\u5bfe\u8c61\u72b6\u614b +message.acquire.new.ip.vpc=\u3053\u306e VPC \u306e\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.acquire.new.ip=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.acquire.new.ip.vpc=VPC\u306e\u65b0\u3057\u3044IP\u3092\u53d6\u5f97\u3059\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.acquire.public.ip=\u65b0\u3057\u3044 IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3059\u308b\u30be\u30fc\u30f3\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.action.cancel.maintenance.mode=\u3053\u306e\u4fdd\u5b88\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.cancel.maintenance.mode=\u3053\u306e\u4fdd\u5b88\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.cancel.maintenance=\u30db\u30b9\u30c8\u306e\u4fdd\u5b88\u306f\u6b63\u5e38\u306b\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f\u3002\u3053\u306e\u51e6\u7406\u306b\u306f\u6570\u5206\u304b\u304b\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 message.action.change.service.warning.for.instance=\u73fe\u5728\u306e\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u5909\u66f4\u3059\u308b\u524d\u306b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u505c\u6b62\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.action.change.service.warning.for.router=\u73fe\u5728\u306e\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u5909\u66f4\u3059\u308b\u524d\u306b\u30eb\u30fc\u30bf\u30fc\u3092\u505c\u6b62\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 -message.action.delete.cluster=\u3053\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.delete.cluster=\u3053\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.disk.offering=\u3053\u306e\u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.delete.domain=\u3053\u306e\u30c9\u30e1\u30a4\u30f3\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.delete.external.firewall=\u3053\u306e\u5916\u90e8\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u8b66\u544a: \u540c\u3058\u5916\u90e8\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u518d\u5ea6\u8ffd\u52a0\u3059\u308b\u4e88\u5b9a\u3067\u3042\u308b\u5834\u5408\u306f\u3001\u30c7\u30d0\u30a4\u30b9\u306e\u4f7f\u7528\u72b6\u6cc1\u30c7\u30fc\u30bf\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 -message.action.delete.external.load.balancer=\u3053\u306e\u5916\u90e8\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u8b66\u544a: \u540c\u3058\u5916\u90e8\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u3092\u518d\u5ea6\u8ffd\u52a0\u3059\u308b\u4e88\u5b9a\u3067\u3042\u308b\u5834\u5408\u306f\u3001\u30c7\u30d0\u30a4\u30b9\u306e\u4f7f\u7528\u72b6\u6cc1\u30c7\u30fc\u30bf\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +message.action.delete.domain=\u3053\u306e\u30c9\u30e1\u30a4\u30f3\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.delete.external.firewall=\u3053\u306e\u5916\u90e8\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u8b66\u544a\: \u540c\u3058\u5916\u90e8\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u518d\u5ea6\u8ffd\u52a0\u3059\u308b\u4e88\u5b9a\u3067\u3042\u308b\u5834\u5408\u306f\u3001\u30c7\u30d0\u30a4\u30b9\u306e\u4f7f\u7528\u72b6\u6cc1\u30c7\u30fc\u30bf\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +message.action.delete.external.load.balancer=\u3053\u306e\u5916\u90e8\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u8b66\u544a\: \u540c\u3058\u5916\u90e8\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u3092\u518d\u5ea6\u8ffd\u52a0\u3059\u308b\u4e88\u5b9a\u3067\u3042\u308b\u5834\u5408\u306f\u3001\u30c7\u30d0\u30a4\u30b9\u306e\u4f7f\u7528\u72b6\u6cc1\u30c7\u30fc\u30bf\u3092\u30ea\u30bb\u30c3\u30c8\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.action.delete.ingress.rule=\u3053\u306e\u53d7\u4fe1\u898f\u5247\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.delete.ISO.for.all.zones=\u305d\u306e ISO \u306f\u3059\u3079\u3066\u306e\u30be\u30fc\u30f3\u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3059\u3079\u3066\u306e\u30be\u30fc\u30f3\u304b\u3089\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.delete.ISO.for.all.zones=\u305d\u306e ISO \u306f\u3059\u3079\u3066\u306e\u30be\u30fc\u30f3\u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3059\u3079\u3066\u306e\u30be\u30fc\u30f3\u304b\u3089\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.ISO=\u3053\u306e ISO \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.network=\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.nexusVswitch=\u3053\u306e Nexus 1000V \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1153,7 +1217,7 @@ message.action.delete.security.group=\u3053\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\ message.action.delete.service.offering=\u3053\u306e\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.snapshot=\u3053\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.system.service.offering=\u3053\u306e\u30b7\u30b9\u30c6\u30e0 \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.delete.template.for.all.zones=\u305d\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306f\u3059\u3079\u3066\u306e\u30be\u30fc\u30f3\u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3059\u3079\u3066\u306e\u30be\u30fc\u30f3\u304b\u3089\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.delete.template.for.all.zones=\u305d\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306f\u3059\u3079\u3066\u306e\u30be\u30fc\u30f3\u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3059\u3079\u3066\u306e\u30be\u30fc\u30f3\u304b\u3089\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.template=\u3053\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.volume=\u3053\u306e\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.delete.zone=\u3053\u306e\u30be\u30fc\u30f3\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1177,11 +1241,11 @@ message.action.force.reconnect=\u30db\u30b9\u30c8\u306f\u5f37\u5236\u7684\u306b\ message.action.host.enable.maintenance.mode=\u4fdd\u5b88\u30e2\u30fc\u30c9\u3092\u6709\u52b9\u306b\u3059\u308b\u3068\u3001\u3053\u306e\u30db\u30b9\u30c8\u3067\u5b9f\u884c\u4e2d\u306e\u3059\u3079\u3066\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u307b\u304b\u306e\u4f7f\u7528\u3067\u304d\u308b\u30db\u30b9\u30c8\u306b\u30e9\u30a4\u30d6 \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3055\u308c\u307e\u3059\u3002 message.action.instance.reset.password=\u3053\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u30eb\u30fc\u30c8 \u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5909\u66f4\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.manage.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u7ba1\u7406\u5bfe\u8c61\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.primarystorage.enable.maintenance.mode=\u8b66\u544a: \u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4fdd\u5b88\u30e2\u30fc\u30c9\u306b\u3059\u308b\u3068\u3001\u305d\u306e\u30b9\u30c8\u30ec\u30fc\u30b8\u4e0a\u306e\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u4f7f\u7528\u3059\u308b\u3059\u3079\u3066\u306e VM \u304c\u505c\u6b62\u3057\u307e\u3059\u3002\u7d9a\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.primarystorage.enable.maintenance.mode=\u8b66\u544a\: \u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4fdd\u5b88\u30e2\u30fc\u30c9\u306b\u3059\u308b\u3068\u3001\u305d\u306e\u30b9\u30c8\u30ec\u30fc\u30b8\u4e0a\u306e\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u4f7f\u7528\u3059\u308b\u3059\u3079\u3066\u306e VM \u304c\u505c\u6b62\u3057\u307e\u3059\u3002\u7d9a\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.reboot.instance=\u3053\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u518d\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.reboot.router=\u3053\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u3067\u63d0\u4f9b\u3059\u308b\u3059\u3079\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u304c\u4e2d\u65ad\u3055\u308c\u307e\u3059\u3002\u3053\u306e\u30eb\u30fc\u30bf\u30fc\u3092\u518d\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.reboot.systemvm=\u3053\u306e\u30b7\u30b9\u30c6\u30e0 VM \u3092\u518d\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.action.release.ip=\u3053\u306e IP \u30a2\u30c9\u30ec\u30b9\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.reboot.systemvm=\u3053\u306e\u30b7\u30b9\u30c6\u30e0 VM \u3092\u518d\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.release.ip=\u3053\u306e IP \u30a2\u30c9\u30ec\u30b9\u3092\u89e3\u653e\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.remove.host=\u3053\u306e\u30db\u30b9\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.reset.password.off=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306f\u73fe\u5728\u3053\u306e\u6a5f\u80fd\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002 message.action.reset.password.warning=\u73fe\u5728\u306e\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5909\u66f4\u3059\u308b\u524d\u306b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u505c\u6b62\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 @@ -1194,44 +1258,48 @@ message.action.stop.router=\u3053\u306e\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u306 message.action.stop.systemvm=\u3053\u306e\u30b7\u30b9\u30c6\u30e0 VM \u3092\u505c\u6b62\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.take.snapshot=\u3053\u306e\u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.action.unmanage.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u975e\u7ba1\u7406\u5bfe\u8c61\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.vmsnapshot.delete=\u3053\u306e VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.action.vmsnapshot.revert=VM \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u5143\u306b\u623b\u3059 message.activate.project=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u30a2\u30af\u30c6\u30a3\u30d6\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.add.cluster=\u30be\u30fc\u30f3 \u306e\u30dd\u30c3\u30c9 \u306b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3067\u7ba1\u7406\u3055\u308c\u308b\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059 -message.add.cluster.zone=\u30be\u30fc\u30f3 \u306b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3067\u7ba1\u7406\u3055\u308c\u308b\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.cluster.zone=\u30be\u30fc\u30f3 \u306b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3067\u7ba1\u7406\u3055\u308c\u308b\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.cluster=\u30be\u30fc\u30f3 \u306e\u30dd\u30c3\u30c9 \u306b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3067\u7ba1\u7406\u3055\u308c\u308b\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.disk.offering=\u65b0\u3057\u3044\u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.domain=\u3053\u306e\u30c9\u30e1\u30a4\u30f3\u306b\u4f5c\u6210\u3059\u308b\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.firewall=\u30be\u30fc\u30f3\u306b\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.guest.network=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u8ffd\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.add.host=\u65b0\u3057\u3044\u30db\u30b9\u30c8\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.adding.host=\u30db\u30b9\u30c8\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -message.adding.Netscaler.device=Netscaler \u30c7\u30d0\u30a4\u30b9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -message.adding.Netscaler.provider=Netscaler \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 -message.add.ip.range.direct.network=\u30be\u30fc\u30f3 \u306e\u76f4\u63a5\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u8ffd\u52a0\u3057\u307e\u3059 -message.add.ip.range.to.pod=

\u30dd\u30c3\u30c9 \u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u8ffd\u52a0\u3057\u307e\u3059

+message.add.ip.range.direct.network=\u30be\u30fc\u30f3 \u306e\u76f4\u63a5\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.ip.range.to.pod=

\u30dd\u30c3\u30c9 \u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u8ffd\u52a0\u3057\u307e\u3059

message.add.ip.range=\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u8ffd\u52a0\u3057\u307e\u3059 -message.additional.networks.desc=\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u63a5\u7d9a\u3059\u308b\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.add.load.balancer.under.ip=\u8ca0\u8377\u5206\u6563\u898f\u5247\u304c\u6b21\u306e IP \u30a2\u30c9\u30ec\u30b9\u306b\u5bfe\u3057\u3066\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\: message.add.load.balancer=\u30be\u30fc\u30f3\u306b\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u3092\u8ffd\u52a0\u3057\u307e\u3059 -message.add.load.balancer.under.ip=\u8ca0\u8377\u5206\u6563\u898f\u5247\u304c\u6b21\u306e IP \u30a2\u30c9\u30ec\u30b9\u306b\u5bfe\u3057\u3066\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f: -message.add.network=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.network=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.new.gateway.to.vpc=\u3053\u306e VPC \u306b\u65b0\u3057\u3044\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306e\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.add.pod=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u307e\u3059 -message.add.primary.storage=\u30be\u30fc\u30f3 \u306e\u30dd\u30c3\u30c9 \u306b\u65b0\u3057\u3044\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.pod.during.zone.creation=\u5404\u30be\u30fc\u30f3\u306b\u306f 1 \u3064\u4ee5\u4e0a\u306e\u30dd\u30c3\u30c9\u304c\u5fc5\u8981\u3067\u3059\u3002\u4eca\u3053\u3053\u3067\u6700\u521d\u306e\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002\u30dd\u30c3\u30c9\u306f\u30db\u30b9\u30c8\u3068\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u304b\u3089\u69cb\u6210\u3055\u308c\u307e\u3059\u304c\u3001\u3053\u308c\u3089\u306f\u5f8c\u306e\u624b\u9806\u3067\u8ffd\u52a0\u3057\u307e\u3059\u3002\u6700\u521d\u306b\u3001CloudStack \u306e\u5185\u90e8\u7ba1\u7406\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u305f\u3081\u306b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u4e88\u7d04\u3057\u307e\u3059\u3002IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306f\u3001\u30af\u30e9\u30a6\u30c9\u5185\u306e\u5404\u30be\u30fc\u30f3\u3067\u91cd\u8907\u3057\u306a\u3044\u3088\u3046\u306b\u4e88\u7d04\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +message.add.pod=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.primary.storage=\u30be\u30fc\u30f3 \u306e\u30dd\u30c3\u30c9 \u306b\u65b0\u3057\u3044\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3059 message.add.primary=\u65b0\u3057\u3044\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.add.secondary.storage=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3059 -message.add.service.offering=\u65b0\u3057\u3044\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.add.system.service.offering=\u65b0\u3057\u3044\u30b7\u30b9\u30c6\u30e0 \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.add.region=\u65b0\u3057\u3044\u9818\u57df\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u5fc5\u8981\u306a\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.add.secondary.storage=\u30be\u30fc\u30f3 \u306b\u65b0\u3057\u3044\u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u307e\u3059 +message.add.service.offering=\u65b0\u3057\u3044\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.add.system.service.offering=\u65b0\u3057\u3044\u30b7\u30b9\u30c6\u30e0 \u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.template=\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.volume=\u65b0\u3057\u3044\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.add.VPN.gateway=VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3092\u8ffd\u52a0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.adding.host=\u30db\u30b9\u30c8\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +message.adding.Netscaler.device=Netscaler \u30c7\u30d0\u30a4\u30b9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +message.adding.Netscaler.provider=Netscaler \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059 +message.additional.networks.desc=\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u63a5\u7d9a\u3059\u308b\u8ffd\u52a0\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.advanced.mode.desc=VLAN \u30b5\u30dd\u30fc\u30c8\u3092\u6709\u52b9\u306b\u3059\u308b\u5834\u5408\u306f\u3001\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u30e2\u30c7\u30eb\u3067\u306f\u6700\u3082\u67d4\u8edf\u306b\u30ab\u30b9\u30bf\u30e0 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u63d0\u4f9b\u3067\u304d\u3001\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3001VPN\u3001\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u306e\u30b5\u30dd\u30fc\u30c8\u306e\u307b\u304b\u306b\u3001\u76f4\u63a5\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3068\u4eee\u60f3\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3082\u6709\u52b9\u306b\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 message.advanced.security.group=\u30b2\u30b9\u30c8 VM \u3092\u5206\u96e2\u3059\u308b\u305f\u3081\u306b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306f\u3001\u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.advanced.virtual=\u30b2\u30b9\u30c8 VM \u3092\u5206\u96e2\u3059\u308b\u305f\u3081\u306b\u30be\u30fc\u30f3\u5168\u4f53\u306e VLAN \u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306f\u3001\u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.after.enable.s3=S3\u57fa\u76e4\u30bb\u30ab\u30f3\u30c0\u30ea\u30b9\u30c8\u30ec\u30fc\u30b8\u304c\u8a2d\u5b9a\u3055\u308c\u307e\u3057\u305f\u3002 \u30ce\u30fc\u30c8:\u3053\u306e\u30da\u30fc\u30b8\u3092\u9589\u3058\u308b\u3068S3\u3092\u518d\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093\u3002 -message.after.enable.swift=Swift \u304c\u69cb\u6210\u3055\u308c\u307e\u3057\u305f\u3002\u6ce8: \u3053\u306e\u30da\u30fc\u30b8\u3092\u9589\u3058\u308b\u3068\u3001Swift \u3092\u518d\u69cb\u6210\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002 +message.after.enable.s3=S3 \u30d9\u30fc\u30b9\u306e\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u304c\u69cb\u6210\u3055\u308c\u307e\u3057\u305f\u3002\u6ce8\: \u3053\u306e\u30da\u30fc\u30b8\u3092\u9589\u3058\u308b\u3068\u3001S3 \u3092\u518d\u69cb\u6210\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002 +message.after.enable.swift=Swift \u304c\u69cb\u6210\u3055\u308c\u307e\u3057\u305f\u3002\u6ce8\: \u3053\u306e\u30da\u30fc\u30b8\u3092\u9589\u3058\u308b\u3068\u3001Swift \u3092\u518d\u69cb\u6210\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002 message.alert.state.detected=\u30a2\u30e9\u30fc\u30c8\u72b6\u614b\u304c\u691c\u51fa\u3055\u308c\u307e\u3057\u305f message.allow.vpn.access=VPN \u30a2\u30af\u30bb\u30b9\u3092\u8a31\u53ef\u3059\u308b\u30e6\u30fc\u30b6\u30fc\u306e\u30e6\u30fc\u30b6\u30fc\u540d\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.apply.snapshot.policy=\u73fe\u5728\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 \u30dd\u30ea\u30b7\u30fc\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002 message.attach.iso.confirm=\u3053\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b ISO \u30d5\u30a1\u30a4\u30eb\u3092\u30a2\u30bf\u30c3\u30c1\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.attach.volume=\u65b0\u3057\u3044\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30a2\u30bf\u30c3\u30c1\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002Windows \u30d9\u30fc\u30b9\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306b\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30a2\u30bf\u30c3\u30c1\u3059\u308b\u5834\u5408\u306f\u3001\u30a2\u30bf\u30c3\u30c1\u3057\u305f\u30c7\u30a3\u30b9\u30af\u3092\u8a8d\u8b58\u3059\u308b\u305f\u3081\u306b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u518d\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +message.attach.volume=\u65b0\u3057\u3044\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30a2\u30bf\u30c3\u30c1\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002Windows \u30d9\u30fc\u30b9\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306b\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30a2\u30bf\u30c3\u30c1\u3059\u308b\u5834\u5408\u306f\u3001\u30a2\u30bf\u30c3\u30c1\u3057\u305f\u30c7\u30a3\u30b9\u30af\u3092\u8a8d\u8b58\u3059\u308b\u305f\u3081\u306b\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u518d\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.basic.mode.desc=VLAN \u30b5\u30dd\u30fc\u30c8\u304c\u4e0d\u8981\u3067\u3042\u308b\u5834\u5408\u306f\u3001\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3067\u4f5c\u6210\u3055\u308c\u308b\u3059\u3079\u3066\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304b\u3089\u76f4\u63a5 IP \u30a2\u30c9\u30ec\u30b9\u304c\u5272\u308a\u5f53\u3066\u3089\u308c\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u4f7f\u7528\u3057\u3066\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u5206\u96e2\u304c\u63d0\u4f9b\u3055\u308c\u307e\u3059\u3002 message.change.offering.confirm=\u3053\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u5909\u66f4\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.change.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002 @@ -1251,10 +1319,10 @@ message.confirm.join.project=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3 message.confirm.remove.IP.range=\u3053\u306e IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.confirm.shutdown.provider=\u3053\u306e\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.copy.iso.confirm=ISO \u3092\u6b21\u306e\u5834\u6240\u306b\u30b3\u30d4\u30fc\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.copy.template=\u30be\u30fc\u30f3 \u304b\u3089\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 XXX \u3092\u6b21\u306e\u5834\u6240\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059: +message.copy.template=\u30be\u30fc\u30f3 \u304b\u3089\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 XXX \u3092\u6b21\u306e\u5834\u6240\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\: +message.create.template.vm=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 \u304b\u3089 VM \u3092\u4f5c\u6210\u3057\u307e\u3059 +message.create.template.volume=\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0 \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3059\u308b\u524d\u306b\u3001\u6b21\u306e\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30dc\u30ea\u30e5\u30fc\u30e0 \u30b5\u30a4\u30ba\u306b\u3088\u3063\u3066\u306f\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u4f5c\u6210\u306b\u306f\u6570\u5206\u4ee5\u4e0a\u304b\u304b\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 message.create.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.create.template.vm=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 \u304b\u3089 VM \u3092\u4f5c\u6210\u3057\u307e\u3059 -message.create.template.volume=\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0 \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3059\u308b\u524d\u306b\u3001\u6b21\u306e\u60c5\u5831\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30dc\u30ea\u30e5\u30fc\u30e0 \u30b5\u30a4\u30ba\u306b\u3088\u3063\u3066\u306f\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u4f5c\u6210\u306b\u306f\u6570\u5206\u4ee5\u4e0a\u304b\u304b\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 message.creating.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.creating.guest.network=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.creating.physical.networks=\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 @@ -1263,7 +1331,8 @@ message.creating.primary.storage=\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30 message.creating.secondary.storage=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.creating.zone=\u30be\u30fc\u30f3\u3092\u4f5c\u6210\u3057\u3066\u3044\u307e\u3059 message.decline.invitation=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u62db\u5f85\u3092\u8f9e\u9000\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.delete.account=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.delete.account=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.delete.affinity.group=\u3053\u306e\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.delete.gateway=\u3053\u306e\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.delete.project=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.delete.user=\u3053\u306e\u30e6\u30fc\u30b6\u30fc\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1273,6 +1342,7 @@ message.delete.VPN.gateway=\u3053\u306e VPN \u30b2\u30fc\u30c8\u30a6\u30a7\u30a4 message.desc.advanced.zone=\u3088\u308a\u6d17\u7df4\u3055\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u6280\u8853\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002\u3053\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3092\u9078\u629e\u3059\u308b\u3068\u3001\u3088\u308a\u67d4\u8edf\u306b\u30b2\u30b9\u30c8\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u5b9a\u7fa9\u3057\u3001\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3001VPN\u3001\u8ca0\u8377\u5206\u6563\u88c5\u7f6e\u306e\u30b5\u30dd\u30fc\u30c8\u306e\u3088\u3046\u306a\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3057\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u63d0\u4f9b\u3067\u304d\u307e\u3059\u3002 message.desc.basic.zone=\u5404 VM \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b IP \u30a2\u30c9\u30ec\u30b9\u304c\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304b\u3089\u76f4\u63a5\u5272\u308a\u5f53\u3066\u3089\u308c\u308b\u3001\u5358\u4e00\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u63d0\u4f9b\u3057\u307e\u3059\u3002\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 (\u9001\u4fe1\u5143 IP \u30a2\u30c9\u30ec\u30b9\u306e\u30d5\u30a3\u30eb\u30bf\u30fc) \u306e\u3088\u3046\u306a\u30ec\u30a4\u30e4\u30fc 3 \u30ec\u30d9\u30eb\u306e\u65b9\u6cd5\u3067\u30b2\u30b9\u30c8\u3092\u5206\u96e2\u3067\u304d\u307e\u3059\u3002 message.desc.cluster=\u5404\u30dd\u30c3\u30c9\u306b\u306f 1 \u3064\u4ee5\u4e0a\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u304c\u5fc5\u8981\u3067\u3059\u3002\u4eca\u3053\u3053\u3067\u6700\u521d\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002\u30af\u30e9\u30b9\u30bf\u30fc\u306f\u30db\u30b9\u30c8\u3092\u30b0\u30eb\u30fc\u30d7\u5316\u3059\u308b\u65b9\u6cd5\u3067\u3059\u30021 \u3064\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u5185\u306e\u30db\u30b9\u30c8\u306f\u3059\u3079\u3066\u540c\u4e00\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u304b\u3089\u69cb\u6210\u3055\u308c\u3001\u540c\u3058\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3092\u5b9f\u884c\u3057\u3001\u540c\u3058\u30b5\u30d6\u30cd\u30c3\u30c8\u4e0a\u306b\u3042\u308a\u3001\u540c\u3058\u5171\u6709\u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u5404\u30af\u30e9\u30b9\u30bf\u30fc\u306f 1 \u3064\u4ee5\u4e0a\u306e\u30db\u30b9\u30c8\u3068 1 \u3064\u4ee5\u4e0a\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u304b\u3089\u69cb\u6210\u3055\u308c\u307e\u3059\u3002 +message.desc.host=\u5404\u30af\u30e9\u30b9\u30bf\u30fc\u306b\u306f\u5c11\u306a\u304f\u3068\u3082 1 \u3064\u3001\u30b2\u30b9\u30c8 VM \u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306e\u30db\u30b9\u30c8 (\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc) \u304c\u5fc5\u8981\u3067\u3059\u3002\u4eca\u3053\u3053\u3067\u6700\u521d\u306e\u30db\u30b9\u30c8\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002CloudStack \u3067\u30db\u30b9\u30c8\u3092\u6a5f\u80fd\u3055\u305b\u308b\u306b\u306f\u3001\u30db\u30b9\u30c8\u306b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066 IP \u30a2\u30c9\u30ec\u30b9\u3092\u5272\u308a\u5f53\u3066\u3001\u30db\u30b9\u30c8\u304c CloudStack \u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u306b\u63a5\u7d9a\u3057\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u30db\u30b9\u30c8\u306e DNS \u540d\u307e\u305f\u306f IP \u30a2\u30c9\u30ec\u30b9\u3001\u30e6\u30fc\u30b6\u30fc\u540d (\u901a\u5e38\u306f root) \u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u3001\u304a\u3088\u3073\u30db\u30b9\u30c8\u306e\u5206\u985e\u306b\u4f7f\u7528\u3059\u308b\u30e9\u30d9\u30eb\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.desc.primary.storage=\u5404\u30af\u30e9\u30b9\u30bf\u30fc\u306b\u306f\u5c11\u306a\u304f\u3068\u3082 1 \u3064\u3001\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u304c\u5fc5\u8981\u3067\u3059\u3002\u4eca\u3053\u3053\u3067\u6700\u521d\u306e\u30b5\u30fc\u30d0\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306f\u3001\u30af\u30e9\u30b9\u30bf\u30fc\u5185\u306e\u30db\u30b9\u30c8\u4e0a\u3067\u52d5\u4f5c\u3059\u308b\u3059\u3079\u3066\u306e VM \u306e\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u683c\u7d0d\u3057\u307e\u3059\u3002\u57fa\u790e\u3068\u306a\u308b\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3067\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u308b\u3001\u6a19\u6e96\u306b\u6e96\u62e0\u3057\u305f\u30d7\u30ed\u30c8\u30b3\u30eb\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.desc.secondary.storage=\u5404\u30be\u30fc\u30f3\u306b\u306f\u5c11\u306a\u304f\u3068\u3082 1 \u3064\u3001NFS \u3064\u307e\u308a\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u304c\u5fc5\u8981\u3067\u3059\u3002\u4eca\u3053\u3053\u3067\u6700\u521d\u306e\u30b5\u30fc\u30d0\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306f VM \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3001ISO \u30a4\u30e1\u30fc\u30b8\u3001\u304a\u3088\u3073VM \u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u683c\u7d0d\u3057\u307e\u3059\u3002\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u306f\u30be\u30fc\u30f3\u5185\u306e\u3059\u3079\u3066\u306e\u30db\u30b9\u30c8\u3067\u4f7f\u7528\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002

IP \u30a2\u30c9\u30ec\u30b9\u3068\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u305f\u30d1\u30b9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.desc.zone=\u30be\u30fc\u30f3\u306f CloudStack \u74b0\u5883\u5185\u306e\u6700\u5927\u306e\u7d44\u7e54\u5358\u4f4d\u3067\u3001\u901a\u5e38\u3001\u5358\u4e00\u306e\u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306b\u76f8\u5f53\u3057\u307e\u3059\u3002\u30be\u30fc\u30f3\u306b\u3088\u3063\u3066\u7269\u7406\u7684\u306a\u5206\u96e2\u3068\u5197\u9577\u6027\u304c\u63d0\u4f9b\u3055\u308c\u307e\u3059\u3002\u30be\u30fc\u30f3\u306f 1 \u3064\u4ee5\u4e0a\u306e\u30dd\u30c3\u30c9 (\u5404\u30dd\u30c3\u30c9\u306f\u30db\u30b9\u30c8\u3068\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u304b\u3089\u69cb\u6210\u3055\u308c\u307e\u3059) \u3068\u3001\u30be\u30fc\u30f3\u5185\u306e\u3059\u3079\u3066\u306e\u30dd\u30c3\u30c9\u3067\u5171\u6709\u3055\u308c\u308b\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u304b\u3089\u69cb\u6210\u3055\u308c\u307e\u3059\u3002 @@ -1283,20 +1353,20 @@ message.disable.snapshot.policy=\u73fe\u5728\u306e\u30b9\u30ca\u30c3\u30d7\u30b7 message.disable.user=\u3053\u306e\u30e6\u30fc\u30b6\u30fc\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.disable.vpn.access=VPN \u30a2\u30af\u30bb\u30b9\u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.disable.vpn=VPN \u3092\u7121\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.download.ISO=ISO \u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f 00000 \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059 -message.download.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f 00000 \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059 +message.download.ISO=ISO \u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f 00000 \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059 +message.download.template=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f 00000 \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059 message.download.volume.confirm=\u3053\u306e\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.download.volume=\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f 00000 \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059 +message.download.volume=\u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f 00000 \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059 message.edit.account=\u7de8\u96c6 ("-1" \u306f\u3001\u30ea\u30bd\u30fc\u30b9\u4f5c\u6210\u306e\u91cf\u306b\u5236\u9650\u304c\u306a\u3044\u3053\u3068\u3092\u793a\u3057\u307e\u3059) message.edit.confirm=[\u4fdd\u5b58] \u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u524d\u306b\u5909\u66f4\u5185\u5bb9\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.edit.limits=\u6b21\u306e\u30ea\u30bd\u30fc\u30b9\u306b\u5236\u9650\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u300c-1\u300d\u306f\u3001\u30ea\u30bd\u30fc\u30b9\u4f5c\u6210\u306b\u5236\u9650\u304c\u306a\u3044\u3053\u3068\u3092\u793a\u3057\u307e\u3059\u3002 message.edit.traffic.type=\u3053\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u7a2e\u985e\u306b\u95a2\u9023\u4ed8\u3051\u308b\u30c8\u30e9\u30d5\u30a3\u30c3\u30af \u30e9\u30d9\u30eb\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.enable.account=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.enabled.vpn.ip.sec=IPSec \u4e8b\u524d\u5171\u6709\u30ad\u30fc: -message.enabled.vpn=\u73fe\u5728\u3001VPN \u30a2\u30af\u30bb\u30b9\u304c\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u6b21\u306e IP \u30a2\u30c9\u30ec\u30b9\u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002 message.enable.user=\u3053\u306e\u30e6\u30fc\u30b6\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.enable.vpn.access=\u73fe\u5728\u3053\u306e IP \u30a2\u30c9\u30ec\u30b9\u306b\u5bfe\u3059\u308b VPN \u306f\u7121\u52b9\u3067\u3059\u3002VPN \u30a2\u30af\u30bb\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.enable.vpn=\u3053\u306e IP \u30a2\u30c9\u30ec\u30b9\u306b\u5bfe\u3059\u308b VPN \u30a2\u30af\u30bb\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.enabled.vpn.ip.sec=IPSec \u4e8b\u524d\u5171\u6709\u30ad\u30fc: +message.enabled.vpn=\u73fe\u5728\u3001VPN \u30a2\u30af\u30bb\u30b9\u304c\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u6b21\u306e IP \u30a2\u30c9\u30ec\u30b9\u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002 message.enabling.security.group.provider=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7 \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 message.enabling.zone=\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u3044\u307e\u3059 message.enter.token=\u96fb\u5b50\u30e1\u30fc\u30eb\u306e\u62db\u5f85\u72b6\u306b\u8a18\u8f09\u3055\u308c\u3066\u3044\u308b\u30c8\u30fc\u30af\u30f3\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 @@ -1304,38 +1374,44 @@ message.generate.keys=\u3053\u306e\u30e6\u30fc\u30b6\u30fc\u306b\u65b0\u3057\u30 message.guest.traffic.in.advanced.zone=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306f\u3001\u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u9593\u306e\u901a\u4fe1\u3067\u3059\u3002\u5404\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30b2\u30b9\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u901a\u4fe1\u3059\u308b\u305f\u3081\u306e VLAN ID \u306e\u7bc4\u56f2\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.guest.traffic.in.basic.zone=\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306f\u3001\u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u9593\u306e\u901a\u4fe1\u3067\u3059\u3002CloudStack \u3067\u30b2\u30b9\u30c8 VM \u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u308b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u306e\u7bc4\u56f2\u304c\u4e88\u7d04\u6e08\u307f\u306e\u30b7\u30b9\u30c6\u30e0 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3068\u91cd\u8907\u3057\u306a\u3044\u3088\u3046\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.installWizard.click.retry=\u8d77\u52d5\u3092\u518d\u8a66\u884c\u3059\u308b\u306b\u306f\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.installWizard.copy.whatIsAPod=\u901a\u5e38\u30011 \u3064\u306e\u30dd\u30c3\u30c9\u306f\u5358\u4e00\u306e\u30e9\u30c3\u30af\u3092\u8868\u3057\u307e\u3059\u3002\u540c\u3058\u30dd\u30c3\u30c9\u5185\u306e\u30db\u30b9\u30c8\u306f\u540c\u3058\u30b5\u30d6\u30cd\u30c3\u30c8\u306b\u542b\u307e\u308c\u307e\u3059\u3002

\u30dd\u30c3\u30c9\u306f CloudStack™ \u74b0\u5883\u5185\u306e 2 \u756a\u76ee\u306b\u5927\u304d\u306a\u7d44\u7e54\u5358\u4f4d\u3067\u3059\u3002\u30dd\u30c3\u30c9\u306f\u30be\u30fc\u30f3\u306b\u542b\u307e\u308c\u307e\u3059\u3002\u5404\u30be\u30fc\u30f3\u306f 1 \u3064\u4ee5\u4e0a\u306e\u30dd\u30c3\u30c9\u3092\u542b\u3080\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u57fa\u672c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u306f\u3001\u30be\u30fc\u30f3\u5185\u306e\u30dd\u30c3\u30c9\u306f 1 \u3064\u3067\u3059\u3002 -message.installWizard.copy.whatIsAZone=\u30be\u30fc\u30f3\u306f CloudStack™ \u74b0\u5883\u5185\u306e\u6700\u5927\u306e\u7d44\u7e54\u5358\u4f4d\u3067\u3059\u30021 \u3064\u306e\u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u5185\u306b\u8907\u6570\u306e\u30be\u30fc\u30f3\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u3059\u304c\u3001\u901a\u5e38\u3001\u30be\u30fc\u30f3\u306f\u5358\u4e00\u306e\u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306b\u76f8\u5f53\u3057\u307e\u3059\u3002\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3092\u30be\u30fc\u30f3\u306b\u7d44\u7e54\u5316\u3059\u308b\u3068\u3001\u30be\u30fc\u30f3\u3092\u7269\u7406\u7684\u306b\u5206\u96e2\u3057\u3066\u5197\u9577\u5316\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u305f\u3068\u3048\u3070\u3001\u5404\u30be\u30fc\u30f3\u306b\u96fb\u6e90\u3068\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30a2\u30c3\u30d7\u30ea\u30f3\u30af\u3092\u914d\u5099\u3057\u307e\u3059\u3002\u5fc5\u9808\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u304c\u3001\u30be\u30fc\u30f3\u306f\u9060\u9694\u5730\u306b\u5206\u6563\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 +message.installWizard.copy.whatIsACluster=\u30af\u30e9\u30b9\u30bf\u30fc\u306f\u30db\u30b9\u30c8\u3092\u30b0\u30eb\u30fc\u30d7\u5316\u3059\u308b\u65b9\u6cd5\u3067\u3059\u30021 \u3064\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u5185\u306e\u30db\u30b9\u30c8\u306f\u3059\u3079\u3066\u540c\u4e00\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u304b\u3089\u69cb\u6210\u3055\u308c\u3001\u540c\u3058\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc\u3092\u5b9f\u884c\u3057\u3001\u540c\u3058\u30b5\u30d6\u30cd\u30c3\u30c8\u4e0a\u306b\u3042\u308a\u3001\u540c\u3058\u5171\u6709\u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u540c\u3058\u30af\u30e9\u30b9\u30bf\u30fc\u5185\u306e\u30db\u30b9\u30c8\u9593\u3067\u306f\u3001\u30e6\u30fc\u30b6\u30fc\u3078\u306e\u30b5\u30fc\u30d3\u30b9\u3092\u4e2d\u65ad\u305b\u305a\u306b\u3001\u4eee\u60f3\u30de\u30b7\u30f3 \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u30e9\u30a4\u30d6 \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u30af\u30e9\u30b9\u30bf\u30fc\u306f CloudStack&\#8482; \u74b0\u5883\u5185\u306e 3 \u756a\u76ee\u306b\u5927\u304d\u306a\u7d44\u7e54\u5358\u4f4d\u3067\u3059\u3002\u30af\u30e9\u30b9\u30bf\u30fc\u306f\u30dd\u30c3\u30c9\u306b\u542b\u307e\u308c\u3001\u30dd\u30c3\u30c9\u306f\u30be\u30fc\u30f3\u306b\u542b\u307e\u308c\u307e\u3059\u3002

CloudStack&\#8482; \u3067\u306f 1 \u3064\u306e\u30af\u30e9\u30a6\u30c9\u74b0\u5883\u306b\u8907\u6570\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u3059\u304c\u3001\u57fa\u672c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u306f\u30af\u30e9\u30b9\u30bf\u30fc\u306f 1 \u3064\u3067\u3059\u3002 +message.installWizard.copy.whatIsAHost=\u30db\u30b9\u30c8\u306f\u5358\u4e00\u306e\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc\u3067\u3001\u30b2\u30b9\u30c8\u4eee\u60f3\u30de\u30b7\u30f3\u3092\u5b9f\u884c\u3059\u308b\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30ea\u30bd\u30fc\u30b9\u3092\u63d0\u4f9b\u3057\u307e\u3059\u3002\u30d9\u30a2 \u30e1\u30bf\u30eb \u30db\u30b9\u30c8\u3092\u9664\u3044\u3066\u3001\u5404\u30db\u30b9\u30c8\u306b\u306f\u30b2\u30b9\u30c8\u4eee\u60f3\u30de\u30b7\u30f3\u3092\u7ba1\u7406\u3059\u308b\u305f\u3081\u306e\u30cf\u30a4\u30d1\u30fc\u30d0\u30a4\u30b6\u30fc \u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002\u30d9\u30a2 \u30e1\u30bf\u30eb \u30db\u30b9\u30c8\u306b\u3064\u3044\u3066\u306f\u3001\u300e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30ac\u30a4\u30c9\u4e0a\u7d1a\u7de8\u300f\u3067\u7279\u6b8a\u4f8b\u3068\u3057\u3066\u8aac\u660e\u3057\u307e\u3059\u3002\u305f\u3068\u3048\u3070\u3001KVM \u304c\u6709\u52b9\u306a Linux \u30b5\u30fc\u30d0\u30fc\u3001Citrix XenServer \u304c\u52d5\u4f5c\u3059\u308b\u30b5\u30fc\u30d0\u30fc\u3001\u304a\u3088\u3073 ESXi \u30b5\u30fc\u30d0\u30fc\u304c\u30db\u30b9\u30c8\u3067\u3059\u3002\u57fa\u672c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u306f\u3001XenServer \u307e\u305f\u306f KVM \u3092\u5b9f\u884c\u3059\u308b\u5358\u4e00\u306e\u30db\u30b9\u30c8\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002

\u30db\u30b9\u30c8\u306f CloudStack&\#8482; \u74b0\u5883\u5185\u306e\u6700\u5c0f\u306e\u7d44\u7e54\u5358\u4f4d\u3067\u3059\u3002\u30db\u30b9\u30c8\u306f\u30af\u30e9\u30b9\u30bf\u30fc\u306b\u542b\u307e\u308c\u3001\u30af\u30e9\u30b9\u30bf\u30fc\u306f\u30dd\u30c3\u30c9\u306b\u542b\u307e\u308c\u3001\u30dd\u30c3\u30c9\u306f\u30be\u30fc\u30f3\u306b\u542b\u307e\u308c\u307e\u3059\u3002 +message.installWizard.copy.whatIsAPod=\u901a\u5e38\u30011 \u3064\u306e\u30dd\u30c3\u30c9\u306f\u5358\u4e00\u306e\u30e9\u30c3\u30af\u3092\u8868\u3057\u307e\u3059\u3002\u540c\u3058\u30dd\u30c3\u30c9\u5185\u306e\u30db\u30b9\u30c8\u306f\u540c\u3058\u30b5\u30d6\u30cd\u30c3\u30c8\u306b\u542b\u307e\u308c\u307e\u3059\u3002

\u30dd\u30c3\u30c9\u306f CloudStack&\#8482; \u74b0\u5883\u5185\u306e 2 \u756a\u76ee\u306b\u5927\u304d\u306a\u7d44\u7e54\u5358\u4f4d\u3067\u3059\u3002\u30dd\u30c3\u30c9\u306f\u30be\u30fc\u30f3\u306b\u542b\u307e\u308c\u307e\u3059\u3002\u5404\u30be\u30fc\u30f3\u306f 1 \u3064\u4ee5\u4e0a\u306e\u30dd\u30c3\u30c9\u3092\u542b\u3080\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u57fa\u672c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u306f\u3001\u30be\u30fc\u30f3\u5185\u306e\u30dd\u30c3\u30c9\u306f 1 \u3064\u3067\u3059\u3002 +message.installWizard.copy.whatIsAZone=\u30be\u30fc\u30f3\u306f CloudStack&\#8482; \u74b0\u5883\u5185\u306e\u6700\u5927\u306e\u7d44\u7e54\u5358\u4f4d\u3067\u3059\u30021 \u3064\u306e\u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u5185\u306b\u8907\u6570\u306e\u30be\u30fc\u30f3\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u3059\u304c\u3001\u901a\u5e38\u3001\u30be\u30fc\u30f3\u306f\u5358\u4e00\u306e\u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u306b\u76f8\u5f53\u3057\u307e\u3059\u3002\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3092\u30be\u30fc\u30f3\u306b\u7d44\u7e54\u5316\u3059\u308b\u3068\u3001\u30be\u30fc\u30f3\u3092\u7269\u7406\u7684\u306b\u5206\u96e2\u3057\u3066\u5197\u9577\u5316\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u305f\u3068\u3048\u3070\u3001\u5404\u30be\u30fc\u30f3\u306b\u96fb\u6e90\u3068\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30a2\u30c3\u30d7\u30ea\u30f3\u30af\u3092\u914d\u5099\u3057\u307e\u3059\u3002\u5fc5\u9808\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u304c\u3001\u30be\u30fc\u30f3\u306f\u9060\u9694\u5730\u306b\u5206\u6563\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 +message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482; \u306f\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30ea\u30bd\u30fc\u30b9\u3092\u30d7\u30fc\u30eb\u3059\u308b\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2 \u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0\u3067\u3001\u30d1\u30d6\u30ea\u30c3\u30af\u3001\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u3001\u304a\u3088\u3073\u30cf\u30a4\u30d6\u30ea\u30c3\u30c9\u306e Infrastructure as a Service (IaaS) \u30af\u30e9\u30a6\u30c9\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002CloudStack&\#8482; \u3092\u4f7f\u7528\u3057\u3066\u3001\u30af\u30e9\u30a6\u30c9 \u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3092\u69cb\u6210\u3059\u308b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3001\u30b9\u30c8\u30ec\u30fc\u30b8\u3001\u304a\u3088\u3073\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30ce\u30fc\u30c9\u3092\u7ba1\u7406\u3057\u3001\u30af\u30e9\u30a6\u30c9 \u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u74b0\u5883\u3092\u5c55\u958b\u3001\u7ba1\u7406\u3001\u304a\u3088\u3073\u69cb\u6210\u3057\u307e\u3059\u3002

CloudStack&\#8482; \u306f\u30b3\u30e2\u30c7\u30a3\u30c6\u30a3\u5316\u3057\u305f\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u4e0a\u3067\u52d5\u4f5c\u3059\u308b\u500b\u5225\u306e\u4eee\u60f3\u30de\u30b7\u30f3 \u30a4\u30e1\u30fc\u30b8\u3092\u8d85\u3048\u3066\u62e1\u5f35\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u3001\u7c21\u5358\u306a\u8a2d\u5b9a\u3067\u52d5\u4f5c\u3059\u308b\u30af\u30e9\u30a6\u30c9 \u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u306e\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2 \u30b9\u30bf\u30c3\u30af\u306b\u3088\u3063\u3066\u3001\u4eee\u60f3\u30c7\u30fc\u30bf\u30bb\u30f3\u30bf\u30fc\u3064\u307e\u308a\u591a\u5c64\u578b\u306e\u30de\u30eb\u30c1\u30c6\u30ca\u30f3\u30c8 \u30af\u30e9\u30a6\u30c9 \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u30b5\u30fc\u30d3\u30b9\u3068\u3057\u3066\u69cb\u7bc9\u3057\u3001\u5c55\u958b\u3057\u3001\u7ba1\u7406\u3059\u308b\u305f\u3081\u306b\u4e0d\u53ef\u6b20\u306a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u304c\u3059\u3079\u3066\u63d0\u4f9b\u3055\u308c\u307e\u3059\u3002\u30aa\u30fc\u30d7\u30f3 \u30bd\u30fc\u30b9 \u30d0\u30fc\u30b8\u30e7\u30f3\u3068\u30d7\u30ec\u30df\u30a2\u30e0 \u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u4e21\u65b9\u304c\u63d0\u4f9b\u3055\u308c\u307e\u3059\u304c\u3001\u30aa\u30fc\u30d7\u30f3 \u30bd\u30fc\u30b9 \u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3082\u307b\u3068\u3093\u3069\u306e\u6a5f\u80fd\u3092\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002 +message.installWizard.copy.whatIsPrimaryStorage=CloudStack&\#8482; \u306e\u30af\u30e9\u30a6\u30c9 \u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3067\u306f\u3001\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3068\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306e 2 \u7a2e\u985e\u306e\u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002\u3069\u3061\u3089\u306e\u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u3082\u3001iSCSI\u3001NFS \u30b5\u30fc\u30d0\u30fc\u3001\u307e\u305f\u306f\u30ed\u30fc\u30ab\u30eb \u30c7\u30a3\u30b9\u30af\u3092\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002

\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306f\u30af\u30e9\u30b9\u30bf\u30fc\u306b\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3001\u305d\u306e\u30af\u30e9\u30b9\u30bf\u30fc\u5185\u306e\u30db\u30b9\u30c8\u3067\u52d5\u4f5c\u3059\u308b\u3059\u3079\u3066\u306e VM \u306e\u5404\u30b2\u30b9\u30c8 VM \u306e\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0\u3092\u683c\u7d0d\u3057\u307e\u3059\u3002\u901a\u5e38\u3001\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 \u30b5\u30fc\u30d0\u30fc\u306f\u30db\u30b9\u30c8\u306e\u8fd1\u304f\u306b\u8a2d\u7f6e\u3057\u307e\u3059\u3002 message.installWizard.copy.whatIsSecondaryStorage=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u306f\u30be\u30fc\u30f3\u3068\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3001\u6b21\u306e\u9805\u76ee\u3092\u683c\u7d0d\u3057\u307e\u3059\u3002
  • \u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 - VM \u306e\u8d77\u52d5\u306b\u4f7f\u7528\u3067\u304d\u308b OS \u30a4\u30e1\u30fc\u30b8\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u306a\u3069\u8ffd\u52a0\u306e\u69cb\u6210\u3092\u542b\u3081\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002
  • ISO \u30a4\u30e1\u30fc\u30b8 - \u8d77\u52d5\u53ef\u80fd\u307e\u305f\u306f\u8d77\u52d5\u4e0d\u53ef\u306e OS \u30a4\u30e1\u30fc\u30b8\u3067\u3059\u3002
  • \u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8 - VM \u30c7\u30fc\u30bf\u306e\u4fdd\u5b58\u30b3\u30d4\u30fc\u3067\u3059\u3002\u30c7\u30fc\u30bf\u306e\u5fa9\u5143\u307e\u305f\u306f\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u4f5c\u6210\u306b\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002
+message.installWizard.now.building=\u30af\u30e9\u30a6\u30c9\u3092\u69cb\u7bc9\u3057\u3066\u3044\u307e\u3059... message.installWizard.tooltip.addCluster.name=\u30af\u30e9\u30b9\u30bf\u30fc\u306e\u540d\u524d\u3067\u3059\u3002CloudStack \u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u306a\u3044\u3001\u4efb\u610f\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u6307\u5b9a\u3067\u304d\u307e\u3059\u3002 message.installWizard.tooltip.addHost.hostname=\u30db\u30b9\u30c8\u306e DNS \u540d\u307e\u305f\u306f IP \u30a2\u30c9\u30ec\u30b9\u3067\u3059\u3002 message.installWizard.tooltip.addHost.password=XenServer \u5074\u3067\u6307\u5b9a\u3057\u305f\u3001\u4e0a\u306e\u30e6\u30fc\u30b6\u30fc\u540d\u306b\u5bfe\u3059\u308b\u30d1\u30b9\u30ef\u30fc\u30c9\u3067\u3059\u3002 message.installWizard.tooltip.addHost.username=\u901a\u5e38\u306f root \u3067\u3059\u3002 message.installWizard.tooltip.addPod.name=\u30dd\u30c3\u30c9\u306e\u540d\u524d\u3067\u3059\u3002 message.installWizard.tooltip.addPod.reservedSystemEndIp=\u3053\u308c\u306f\u3001\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 VM \u304a\u3088\u3073\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7 VM \u3092\u7ba1\u7406\u3059\u308b\u305f\u3081\u306b CloudStack \u3067\u4f7f\u7528\u3059\u308b\u3001\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5185\u306e IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3067\u3059\u3002\u3053\u308c\u3089\u306e IP \u30a2\u30c9\u30ec\u30b9\u306f\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30b5\u30fc\u30d0\u30fc\u3068\u540c\u3058\u30b5\u30d6\u30cd\u30c3\u30c8\u304b\u3089\u5272\u308a\u5f53\u3066\u307e\u3059\u3002 -message.installWizard.tooltip.addPod.reservedSystemGateway=\u3053\u306e\u30dd\u30c3\u30c9\u5185\u306e\u30db\u30b9\u30c8\u306e\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3067\u3059\u3002 -message.installWizard.tooltip.addPod.reservedSystemNetmask=\u30b2\u30b9\u30c8\u306e\u4f7f\u7528\u3059\u308b\u30b5\u30d6\u30cd\u30c3\u30c8\u4e0a\u3067\u4f7f\u7528\u3055\u308c\u308b\u30cd\u30c3\u30c8\u30de\u30b9\u30af\u3067\u3059\u3002 +message.installWizard.tooltip.addPod.reservedSystemGateway=\u3053\u306e\u30dd\u30c3\u30c9\u5185\u306e\u30db\u30b9\u30c8\u306e\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3067\u3059\u3002 +message.installWizard.tooltip.addPod.reservedSystemNetmask=\u30b2\u30b9\u30c8\u306e\u4f7f\u7528\u3059\u308b\u30b5\u30d6\u30cd\u30c3\u30c8\u4e0a\u3067\u4f7f\u7528\u3055\u308c\u308b\u30cd\u30c3\u30c8\u30de\u30b9\u30af\u3067\u3059\u3002 message.installWizard.tooltip.addPod.reservedSystemStartIp=\u3053\u308c\u306f\u3001\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8 VM \u304a\u3088\u3073\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7 VM \u3092\u7ba1\u7406\u3059\u308b\u305f\u3081\u306b CloudStack \u3067\u4f7f\u7528\u3059\u308b\u3001\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5185\u306e IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3067\u3059\u3002\u3053\u308c\u3089\u306e IP \u30a2\u30c9\u30ec\u30b9\u306f\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0 \u30b5\u30fc\u30d0\u30fc\u3068\u540c\u3058\u30b5\u30d6\u30cd\u30c3\u30c8\u304b\u3089\u5272\u308a\u5f53\u3066\u307e\u3059\u3002 message.installWizard.tooltip.addPrimaryStorage.name=\u30b9\u30c8\u30ec\u30fc\u30b8 \u30c7\u30d0\u30a4\u30b9\u306e\u540d\u524d\u3067\u3059\u3002 message.installWizard.tooltip.addPrimaryStorage.path=(NFS \u306e\u5834\u5408) \u30b5\u30fc\u30d0\u30fc\u304b\u3089\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u305f\u30d1\u30b9\u3067\u3059\u3002(SharedMountPoint \u306e\u5834\u5408) \u30d1\u30b9\u3067\u3059\u3002KVM \u3067\u306f\u3053\u306e\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u304c\u30de\u30a6\u30f3\u30c8\u3055\u308c\u308b\u5404\u30db\u30b9\u30c8\u4e0a\u306e\u30d1\u30b9\u3067\u3059\u3002\u305f\u3068\u3048\u3070\u3001/mnt/primary \u3067\u3059\u3002 message.installWizard.tooltip.addPrimaryStorage.server=(NFS\u3001iSCSI\u3001\u307e\u305f\u306f PreSetup \u306e\u5834\u5408) \u30b9\u30c8\u30ec\u30fc\u30b8 \u30c7\u30d0\u30a4\u30b9\u306e IP \u30a2\u30c9\u30ec\u30b9\u307e\u305f\u306f DNS \u540d\u3067\u3059\u3002 message.installWizard.tooltip.addSecondaryStorage.nfsServer=\u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u30db\u30b9\u30c8\u3059\u308b NFS \u30b5\u30fc\u30d0\u30fc\u306e IP \u30a2\u30c9\u30ec\u30b9\u3067\u3059\u3002 message.installWizard.tooltip.addSecondaryStorage.path=\u4e0a\u306b\u6307\u5b9a\u3057\u305f\u30b5\u30fc\u30d0\u30fc\u306b\u5b58\u5728\u3059\u308b\u3001\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3055\u308c\u305f\u30d1\u30b9\u3067\u3059\u3002 -message.installWizard.tooltip.addZone.dns1=\u30be\u30fc\u30f3\u5185\u306e\u30b2\u30b9\u30c8 VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u3067\u3059\u3002\u3053\u308c\u3089\u306e DNS \u30b5\u30fc\u30d0\u30fc\u306b\u306f\u3001\u5f8c\u3067\u8ffd\u52a0\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u3053\u3067\u6307\u5b9a\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af DNS \u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 -message.installWizard.tooltip.addZone.dns2=\u30be\u30fc\u30f3\u5185\u306e\u30b2\u30b9\u30c8 VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u3067\u3059\u3002\u3053\u308c\u3089\u306e DNS \u30b5\u30fc\u30d0\u30fc\u306b\u306f\u3001\u5f8c\u3067\u8ffd\u52a0\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u3053\u3067\u6307\u5b9a\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af DNS \u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +message.installWizard.tooltip.addZone.dns1=\u30be\u30fc\u30f3\u5185\u306e\u30b2\u30b9\u30c8 VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u3067\u3059\u3002\u3053\u308c\u3089\u306e DNS \u30b5\u30fc\u30d0\u30fc\u306b\u306f\u3001\u5f8c\u3067\u8ffd\u52a0\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u3053\u3067\u6307\u5b9a\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af DNS \u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +message.installWizard.tooltip.addZone.dns2=\u30be\u30fc\u30f3\u5185\u306e\u30b2\u30b9\u30c8 VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u3067\u3059\u3002\u3053\u308c\u3089\u306e DNS \u30b5\u30fc\u30d0\u30fc\u306b\u306f\u3001\u5f8c\u3067\u8ffd\u52a0\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u3053\u3067\u6307\u5b9a\u3059\u308b\u30d1\u30d6\u30ea\u30c3\u30af DNS \u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.installWizard.tooltip.addZone.internaldns1=\u30be\u30fc\u30f3\u5185\u306e\u30b7\u30b9\u30c6\u30e0 VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u3067\u3059\u3002\u3053\u308c\u3089\u306e DNS \u30b5\u30fc\u30d0\u30fc\u306f\u3001\u30b7\u30b9\u30c6\u30e0 VM \u306e\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u3092\u4ecb\u3057\u3066\u30a2\u30af\u30bb\u30b9\u3055\u308c\u307e\u3059\u3002\u30dd\u30c3\u30c9\u306e\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u3053\u3067\u6307\u5b9a\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.installWizard.tooltip.addZone.internaldns2=\u30be\u30fc\u30f3\u5185\u306e\u30b7\u30b9\u30c6\u30e0 VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u3067\u3059\u3002\u3053\u308c\u3089\u306e DNS \u30b5\u30fc\u30d0\u30fc\u306f\u3001\u30b7\u30b9\u30c6\u30e0 VM \u306e\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u3092\u4ecb\u3057\u3066\u30a2\u30af\u30bb\u30b9\u3055\u308c\u307e\u3059\u3002\u30dd\u30c3\u30c9\u306e\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u3053\u3067\u6307\u5b9a\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.installWizard.tooltip.addZone.name=\u30be\u30fc\u30f3\u306e\u540d\u524d\u3067\u3059\u3002 message.installWizard.tooltip.configureGuestTraffic.description=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8aac\u660e\u3067\u3059\u3002 message.installWizard.tooltip.configureGuestTraffic.guestEndIp=\u3053\u306e\u30be\u30fc\u30f3\u306e\u30b2\u30b9\u30c8\u306b\u5272\u308a\u5f53\u3066\u308b\u3053\u3068\u304c\u3067\u304d\u308b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3067\u3059\u3002\u4f7f\u7528\u3059\u308b NIC \u304c 1 \u3064\u306e\u5834\u5408\u306f\u3001\u3053\u308c\u3089\u306e IP \u30a2\u30c9\u30ec\u30b9\u306f\u30dd\u30c3\u30c9\u306e CIDR \u3068\u540c\u3058 CIDR \u306b\u542b\u307e\u308c\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.installWizard.tooltip.configureGuestTraffic.guestGateway=\u30b2\u30b9\u30c8\u306e\u4f7f\u7528\u3059\u308b\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3067\u3059\u3002 -message.installWizard.tooltip.configureGuestTraffic.guestNetmask=\u30b2\u30b9\u30c8\u306e\u4f7f\u7528\u3059\u308b\u30b5\u30d6\u30cd\u30c3\u30c8\u4e0a\u3067\u4f7f\u7528\u3055\u308c\u308b\u30cd\u30c3\u30c8\u30de\u30b9\u30af\u3067\u3059\u3002 +message.installWizard.tooltip.configureGuestTraffic.guestNetmask=\u30b2\u30b9\u30c8\u306e\u4f7f\u7528\u3059\u308b\u30b5\u30d6\u30cd\u30c3\u30c8\u4e0a\u3067\u4f7f\u7528\u3055\u308c\u308b\u30cd\u30c3\u30c8\u30de\u30b9\u30af\u3067\u3059\u3002 message.installWizard.tooltip.configureGuestTraffic.guestStartIp=\u3053\u306e\u30be\u30fc\u30f3\u306e\u30b2\u30b9\u30c8\u306b\u5272\u308a\u5f53\u3066\u308b\u3053\u3068\u304c\u3067\u304d\u308b IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3067\u3059\u3002\u4f7f\u7528\u3059\u308b NIC \u304c 1 \u3064\u306e\u5834\u5408\u306f\u3001\u3053\u308c\u3089\u306e IP \u30a2\u30c9\u30ec\u30b9\u306f\u30dd\u30c3\u30c9\u306e CIDR \u3068\u540c\u3058 CIDR \u306b\u542b\u307e\u308c\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.installWizard.tooltip.configureGuestTraffic.name=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u540d\u524d\u3067\u3059\u3002 message.instanceWizard.noTemplates=\u4f7f\u7528\u53ef\u80fd\u306a\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002\u4e92\u63db\u6027\u306e\u3042\u308b\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u8ffd\u52a0\u3057\u3066\u3001\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 \u30a6\u30a3\u30b6\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.ip.address.changed=\u304a\u4f7f\u3044\u306e IP \u30a2\u30c9\u30ec\u30b9\u304c\u5909\u66f4\u3055\u308c\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u4e00\u89a7\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b? \u305d\u306e\u5834\u5408\u306f\u3001\u8a73\u7d30\u30da\u30a4\u30f3\u304c\u9589\u3058\u308b\u3053\u3068\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.iso.desc=\u30c7\u30fc\u30bf\u307e\u305f\u306f OS \u8d77\u52d5\u53ef\u80fd\u30e1\u30c7\u30a3\u30a2\u3092\u542b\u3080\u30c7\u30a3\u30b9\u30af \u30a4\u30e1\u30fc\u30b8 message.join.project=\u3053\u308c\u3067\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u53c2\u52a0\u3057\u307e\u3057\u305f\u3002\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u53c2\u7167\u3059\u308b\u306b\u306f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 \u30d3\u30e5\u30fc\u306b\u5207\u308a\u66ff\u3048\u3066\u304f\u3060\u3055\u3044\u3002 +message.launch.vm.on.private.network=\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u306a\u5c02\u7528\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8d77\u52d5\u3057\u307e\u3059\u304b? message.launch.zone=\u30be\u30fc\u30f3\u3092\u8d77\u52d5\u3059\u308b\u6e96\u5099\u304c\u3067\u304d\u307e\u3057\u305f\u3002\u6b21\u306e\u624b\u9806\u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002 message.lock.account=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u30ed\u30c3\u30af\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u3059\u3079\u3066\u306e\u30e6\u30fc\u30b6\u30fc\u304c\u30af\u30e9\u30a6\u30c9 \u30ea\u30bd\u30fc\u30b9\u3092\u7ba1\u7406\u3067\u304d\u306a\u304f\u306a\u308a\u307e\u3059\u3002\u305d\u306e\u5f8c\u3082\u65e2\u5b58\u306e\u30ea\u30bd\u30fc\u30b9\u306b\u306f\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\u3002 message.migrate.instance.confirm=\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u79fb\u884c\u5148\u306f\u6b21\u306e\u30db\u30b9\u30c8\u3067\u3088\u308d\u3057\u3044\u3067\u3059\u304b? @@ -1365,6 +1441,8 @@ message.please.wait.while.zone.is.being.created=\u30be\u30fc\u30f3\u304c\u4f5c\u message.project.invite.sent=\u30e6\u30fc\u30b6\u30fc\u306b\u62db\u5f85\u72b6\u304c\u9001\u4fe1\u3055\u308c\u307e\u3057\u305f\u3002\u30e6\u30fc\u30b6\u30fc\u304c\u62db\u5f85\u3092\u627f\u8afe\u3059\u308b\u3068\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u8ffd\u52a0\u3055\u308c\u307e\u3059\u3002 message.public.traffic.in.advanced.zone=\u30af\u30e9\u30a6\u30c9\u5185\u306e VM \u304c\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3068\u3001\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u304c\u751f\u6210\u3055\u308c\u307e\u3059\u3002\u3053\u306e\u305f\u3081\u306b\u3001\u4e00\u822c\u306b\u30a2\u30af\u30bb\u30b9\u53ef\u80fd\u306a IP \u30a2\u30c9\u30ec\u30b9\u3092\u5272\u308a\u5f53\u3066\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306f CloudStack \u306e\u30e6\u30fc\u30b6\u30fc \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u3092\u4f7f\u7528\u3057\u3066\u3053\u308c\u3089\u306e IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3001\u30b2\u30b9\u30c8 \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3068\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u9593\u306b NAT \u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002

\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306e\u305f\u3081\u306b\u3001\u5c11\u306a\u304f\u3068\u3082 1 \u3064 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.public.traffic.in.basic.zone=\u30af\u30e9\u30a6\u30c9\u5185\u306e VM \u304c\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u304b\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u7d4c\u7531\u3067\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u30b5\u30fc\u30d3\u30b9\u3092\u63d0\u4f9b\u3059\u308b\u3068\u3001\u30d1\u30d6\u30ea\u30c3\u30af \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u304c\u751f\u6210\u3055\u308c\u307e\u3059\u3002\u3053\u306e\u305f\u3081\u306b\u3001\u4e00\u822c\u306b\u30a2\u30af\u30bb\u30b9\u53ef\u80fd\u306a IP \u30a2\u30c9\u30ec\u30b9\u3092\u5272\u308a\u5f53\u3066\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u4f5c\u6210\u3059\u308b\u3068\u3001\u30b2\u30b9\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u306e\u307b\u304b\u306b\u3053\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u304b\u3089\u30a2\u30c9\u30ec\u30b9\u304c 1 \u3064\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u307e\u3059\u3002\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u3068\u30b2\u30b9\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u306e\u9593\u306b\u3001\u9759\u7684\u306a 1 \u5bfe 1 \u306e NAT \u304c\u81ea\u52d5\u7684\u306b\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3055\u308c\u307e\u3059\u3002\u30a8\u30f3\u30c9 \u30e6\u30fc\u30b6\u30fc\u306f CloudStack \u306e\u30e6\u30fc\u30b6\u30fc \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u3092\u4f7f\u7528\u3057\u3066\u8ffd\u52a0\u306e IP \u30a2\u30c9\u30ec\u30b9\u3092\u53d6\u5f97\u3057\u3001\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3068\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u306e\u9593\u306b\u9759\u7684 NAT \u3092\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\u3002 +message.redirecting.region=\u9818\u57df\u306b\u30ea\u30c0\u30a4\u30ec\u30af\u30c8\u3057\u3066\u3044\u307e\u3059... +message.remove.region=\u3053\u306e\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u304b\u3089\u3053\u306e\u9818\u57df\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.remove.vpc=VPC \u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.remove.vpn.access=\u6b21\u306e\u30e6\u30fc\u30b6\u30fc\u304b\u3089 VPN \u30a2\u30af\u30bb\u30b9\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.reset.password.warning.notPasswordEnabled=\u3053\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306f\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u7ba1\u7406\u3092\u6709\u52b9\u306b\u305b\u305a\u306b\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\u3002 @@ -1387,13 +1465,14 @@ message.setup.successful=\u30af\u30e9\u30a6\u30c9\u304c\u30bb\u30c3\u30c8\u30a2\ message.snapshot.schedule=\u6b21\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u304b\u3089\u9078\u629e\u3057\u3066\u30dd\u30ea\u30b7\u30fc\u306e\u57fa\u672c\u8a2d\u5b9a\u3092\u9069\u7528\u3059\u308b\u3053\u3068\u306b\u3088\u308a\u3001\u5b9a\u671f\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3067\u304d\u307e\u3059\u3002 message.specify.url=URL \u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044 message.step.1.continue=\u7d9a\u884c\u3059\u308b\u306b\u306f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u307e\u305f\u306f ISO \u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 -message.step.1.desc=\u65b0\u3057\u3044\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u7528\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002ISO \u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u304d\u308b\u7a7a\u767d\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u9078\u629e\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\u3002 +message.step.1.desc=\u65b0\u3057\u3044\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u7528\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002ISO \u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u304d\u308b\u7a7a\u767d\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u9078\u629e\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\u3002 message.step.2.continue=\u7d9a\u884c\u3059\u308b\u306b\u306f\u30b5\u30fc\u30d3\u30b9 \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 message.step.2.desc= message.step.3.continue=\u7d9a\u884c\u3059\u308b\u306b\u306f\u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 message.step.3.desc= message.step.4.continue=\u7d9a\u884c\u3059\u308b\u306b\u306f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u5c11\u306a\u304f\u3068\u3082 1 \u3064\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 message.step.4.desc=\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u63a5\u7d9a\u3059\u308b\u30d7\u30e9\u30a4\u30de\u30ea \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +message.storage.traffic=\u30db\u30b9\u30c8\u3084 CloudStack \u30b7\u30b9\u30c6\u30e0 VM \u306a\u3069\u3001\u7ba1\u7406\u30b5\u30fc\u30d0\u30fc\u3068\u901a\u4fe1\u3059\u308b CloudStack \u306e\u5185\u90e8\u30ea\u30bd\u30fc\u30b9\u9593\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3067\u3059\u3002\u3053\u3053\u3067\u30b9\u30c8\u30ec\u30fc\u30b8 \u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u69cb\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.suspend.project=\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u4e00\u6642\u505c\u6b62\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? message.template.desc=VM \u306e\u8d77\u52d5\u306b\u4f7f\u7528\u3067\u304d\u308b OS \u30a4\u30e1\u30fc\u30b8 message.tooltip.dns.1=\u30be\u30fc\u30f3\u5185\u306e VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u306e\u540d\u524d\u3067\u3059\u3002\u30be\u30fc\u30f3\u306e\u30d1\u30d6\u30ea\u30c3\u30af IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 @@ -1402,25 +1481,25 @@ message.tooltip.internal.dns.1=\u30be\u30fc\u30f3\u5185\u306e CloudStack \u5185\ message.tooltip.internal.dns.2=\u30be\u30fc\u30f3\u5185\u306e CloudStack \u5185\u90e8\u30b7\u30b9\u30c6\u30e0 VM \u3067\u4f7f\u7528\u3059\u308b DNS \u30b5\u30fc\u30d0\u30fc\u306e\u540d\u524d\u3067\u3059\u3002\u30dd\u30c3\u30c9\u306e\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8 IP \u30a2\u30c9\u30ec\u30b9\u304b\u3089\u3001\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u306b\u901a\u4fe1\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.tooltip.network.domain=DNS \u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u3067\u3059\u3002\u3053\u306e\u30b5\u30d5\u30a3\u30c3\u30af\u30b9\u304b\u3089\u30b2\u30b9\u30c8 VM \u3067\u30a2\u30af\u30bb\u30b9\u3059\u308b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30ab\u30b9\u30bf\u30e0 \u30c9\u30e1\u30a4\u30f3\u540d\u304c\u4f5c\u6210\u3055\u308c\u307e\u3059\u3002 message.tooltip.pod.name=\u3053\u306e\u30dd\u30c3\u30c9\u306e\u540d\u524d\u3067\u3059\u3002 -message.tooltip.reserved.system.gateway=\u30dd\u30c3\u30c9\u5185\u306e\u30db\u30b9\u30c8\u306e\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3067\u3059\u3002 +message.tooltip.reserved.system.gateway=\u30dd\u30c3\u30c9\u5185\u306e\u30db\u30b9\u30c8\u306e\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u3067\u3059\u3002 message.tooltip.reserved.system.netmask=\u30dd\u30c3\u30c9\u306e\u30b5\u30d6\u30cd\u30c3\u30c8\u3092\u5b9a\u7fa9\u3059\u308b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\u3067\u3059\u3002CIDR \u8868\u8a18\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002 message.tooltip.zone.name=\u30be\u30fc\u30f3\u306e\u540d\u524d\u3067\u3059\u3002 -message.update.os.preference=\u3053\u306e\u30db\u30b9\u30c8\u306e OS \u57fa\u672c\u8a2d\u5b9a\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u540c\u69d8\u306e\u57fa\u672c\u8a2d\u5b9a\u3092\u6301\u3064\u3059\u3079\u3066\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306f\u3001\u5225\u306e\u30db\u30b9\u30c8\u3092\u9078\u629e\u3059\u308b\u524d\u306b\u307e\u305a\u3053\u306e\u30db\u30b9\u30c8\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u307e\u3059\u3002 +message.update.os.preference=\u3053\u306e\u30db\u30b9\u30c8\u306e OS \u57fa\u672c\u8a2d\u5b9a\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u540c\u69d8\u306e\u57fa\u672c\u8a2d\u5b9a\u3092\u6301\u3064\u3059\u3079\u3066\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306f\u3001\u5225\u306e\u30db\u30b9\u30c8\u3092\u9078\u629e\u3059\u308b\u524d\u306b\u307e\u305a\u3053\u306e\u30db\u30b9\u30c8\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u307e\u3059\u3002 message.update.resource.count=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30ea\u30bd\u30fc\u30b9\u6570\u3092\u66f4\u65b0\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? -message.update.ssl=\u5404\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3067\u66f4\u65b0\u3059\u308b\u3001X.509 \u6e96\u62e0\u306e\u65b0\u3057\u3044 SSL \u8a3c\u660e\u66f8\u3092\u9001\u4fe1\u3057\u3066\u304f\u3060\u3055\u3044: +message.update.ssl=\u5404\u30b3\u30f3\u30bd\u30fc\u30eb \u30d7\u30ed\u30ad\u30b7\u306e\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3067\u66f4\u65b0\u3059\u308b\u3001X.509 \u6e96\u62e0\u306e\u65b0\u3057\u3044 SSL \u8a3c\u660e\u66f8\u3092\u9001\u4fe1\u3057\u3066\u304f\u3060\u3055\u3044\: message.validate.instance.name=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u540d\u306f 63 \u6587\u5b57\u4ee5\u5185\u3067\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002ASCII \u6587\u5b57\u306e a\uff5ez\u3001A\uff5eZ\u3001\u6570\u5b57\u306e 0\uff5e9\u3001\u304a\u3088\u3073\u30cf\u30a4\u30d5\u30f3\u306e\u307f\u3092\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002\u6587\u5b57\u3067\u59cb\u307e\u308a\u3001\u6587\u5b57\u307e\u305f\u306f\u6570\u5b57\u3067\u7d42\u308f\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 message.virtual.network.desc=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u5c02\u7528\u4eee\u60f3\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u3059\u3002\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 \u30c9\u30e1\u30a4\u30f3\u306f VLAN \u5185\u306b\u914d\u7f6e\u3055\u308c\u3001\u30d1\u30d6\u30ea\u30c3\u30af \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3078\u306e\u30a2\u30af\u30bb\u30b9\u306f\u3059\u3079\u3066\u4eee\u60f3\u30eb\u30fc\u30bf\u30fc\u306b\u3088\u3063\u3066\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3055\u308c\u307e\u3059\u3002 message.vm.create.template.confirm=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3059\u308b\u3068 VM \u304c\u81ea\u52d5\u7684\u306b\u518d\u8d77\u52d5\u3055\u308c\u307e\u3059\u3002 message.vm.review.launch=\u6b21\u306e\u60c5\u5831\u3092\u53c2\u7167\u3057\u3066\u3001\u4eee\u60f3\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u6b63\u3057\u304f\u8a2d\u5b9a\u3057\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304b\u3089\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.volume.create.template.confirm=\u3053\u306e\u30c7\u30a3\u30b9\u30af \u30dc\u30ea\u30e5\u30fc\u30e0\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? \u30dc\u30ea\u30e5\u30fc\u30e0 \u30b5\u30a4\u30ba\u306b\u3088\u3063\u3066\u306f\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u4f5c\u6210\u306b\u306f\u6570\u5206\u4ee5\u4e0a\u304b\u304b\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 message.you.must.have.at.least.one.physical.network=\u5c11\u306a\u304f\u3068\u3082 1 \u3064\u7269\u7406\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304c\u5fc5\u8981\u3067\u3059 -message.Zone.creation.complete=\u30be\u30fc\u30f3\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f message.zone.creation.complete.would.you.like.to.enable.this.zone=\u30be\u30fc\u30f3\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\u3002\u3053\u306e\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.Zone.creation.complete=\u30be\u30fc\u30f3\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f message.zone.no.network.selection=\u9078\u629e\u3057\u305f\u30be\u30fc\u30f3\u3067\u306f\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u9078\u629e\u3067\u304d\u307e\u305b\u3093\u3002 message.zone.step.1.desc=\u30be\u30fc\u30f3\u306e\u30cd\u30c3\u30c8\u30ef\u30fc\u30af \u30e2\u30c7\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.zone.step.2.desc=\u65b0\u3057\u3044\u30be\u30fc\u30f3\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 message.zone.step.3.desc=\u65b0\u3057\u3044\u30dd\u30c3\u30c9\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3081\u306b\u3001\u6b21\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -message.zoneWizard.enable.local.storage=\u8b66\u544a: \u3053\u306e\u30be\u30fc\u30f3\u306e\u30ed\u30fc\u30ab\u30eb \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u6709\u52b9\u306b\u3059\u308b\u5834\u5408\u306f\u3001\u30b7\u30b9\u30c6\u30e0 VM \u306e\u8d77\u52d5\u5834\u6240\u306b\u5fdc\u3058\u3066\u6b21\u306e\u64cd\u4f5c\u304c\u5fc5\u8981\u3067\u3059\u3002

1. \u30b7\u30b9\u30c6\u30e0 VM \u3092\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3067\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4f5c\u6210\u3057\u305f\u5f8c\u3067\u30be\u30fc\u30f3\u306b\u8ffd\u52a0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u307e\u305f\u3001\u7121\u52b9\u72b6\u614b\u306e\u30be\u30fc\u30f3\u3092\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u3082\u3042\u308a\u307e\u3059\u3002

2. \u30b7\u30b9\u30c6\u30e0 VM \u3092\u30ed\u30fc\u30ab\u30eb \u30b9\u30c8\u30ec\u30fc\u30b8\u3067\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u5834\u5408\u306f\u3001system.vm.use.local.storage \u3092 true \u306b\u8a2d\u5b9a\u3057\u3066\u304b\u3089\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002


\u7d9a\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +message.zoneWizard.enable.local.storage=\u8b66\u544a\: \u3053\u306e\u30be\u30fc\u30f3\u306e\u30ed\u30fc\u30ab\u30eb \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u6709\u52b9\u306b\u3059\u308b\u5834\u5408\u306f\u3001\u30b7\u30b9\u30c6\u30e0 VM \u306e\u8d77\u52d5\u5834\u6240\u306b\u5fdc\u3058\u3066\u6b21\u306e\u64cd\u4f5c\u304c\u5fc5\u8981\u3067\u3059\u3002

1. \u30b7\u30b9\u30c6\u30e0 VM \u3092\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3067\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u30d7\u30e9\u30a4\u30de\u30ea \u30b9\u30c8\u30ec\u30fc\u30b8\u3092\u4f5c\u6210\u3057\u305f\u5f8c\u3067\u30be\u30fc\u30f3\u306b\u8ffd\u52a0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u30be\u30fc\u30f3\u3092\u7121\u52b9\u72b6\u614b\u304b\u3089\u958b\u59cb\u3059\u308b\u5fc5\u8981\u3082\u3042\u308a\u307e\u3059\u3002

2. \u30b7\u30b9\u30c6\u30e0 VM \u3092\u30ed\u30fc\u30ab\u30eb \u30b9\u30c8\u30ec\u30fc\u30b8\u3067\u8d77\u52d5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u30be\u30fc\u30f3\u3092\u6709\u52b9\u306b\u3059\u308b\u524d\u306b system.vm.use.local.storage \u3092 true \u306b\u8a2d\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002


\u7d9a\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? mode=\u30e2\u30fc\u30c9 network.rate=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u901f\u5ea6 notification.reboot.instance=\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u518d\u8d77\u52d5 @@ -1438,14 +1517,14 @@ state.Creating=\u4f5c\u6210\u4e2d state.Declined=\u8f9e\u9000 state.Destroyed=\u7834\u68c4\u6e08\u307f state.Disabled=\u7121\u52b9 -state.enabled=\u6709\u52b9 state.Enabled=\u6709\u52b9 +state.enabled=\u6709\u52b9 state.Error=\u30a8\u30e9\u30fc state.Expunging=\u62b9\u6d88\u4e2d state.Migrating=\u79fb\u884c\u4e2d state.Pending=\u4fdd\u7559 -state.ready=\u6e96\u5099\u5b8c\u4e86 state.Ready=\u6e96\u5099\u5b8c\u4e86 +state.ready=\u6e96\u5099\u5b8c\u4e86 state.Running=\u5b9f\u884c\u4e2d state.Starting=\u958b\u59cb\u4e2d state.Stopped=\u505c\u6b62\u6e08\u307f diff --git a/client/WEB-INF/classes/resources/messages_zh_CN.properties b/client/WEB-INF/classes/resources/messages_zh_CN.properties index 30daacc3627..68ab1562b08 100644 --- a/client/WEB-INF/classes/resources/messages_zh_CN.properties +++ b/client/WEB-INF/classes/resources/messages_zh_CN.properties @@ -14,9 +14,14 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - +label.view.secondary.ips=\u67e5\u770b\u8f85\u52a9 IP +message.acquire.ip.nic=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u83b7\u53d6\u6b64 NIC \u7684\u65b0\u8f85\u52a9 IP\u3002
\u6ce8\u610f: \u60a8\u9700\u8981\u5728\u865a\u62df\u673a\u5185\u90e8\u624b\u52a8\u914d\u7f6e\u65b0\u83b7\u53d6\u7684\u8f85\u52a9 IP\u3002 +message.select.affinity.groups=\u8bf7\u9009\u62e9\u60a8\u5e0c\u671b\u6b64 VM \u6240\u5c5e\u7684\u4efb\u4f55\u5173\u8054\u6027\u7ec4: +message.no.affinity.groups=\u60a8\u6ca1\u6709\u4efb\u4f55\u5173\u8054\u6027\u7ec4\u3002\u8bf7\u7ee7\u7eed\u6267\u884c\u4e0b\u4e00\u6b65\u64cd\u4f5c\u3002 +label.action.delete.nic=\u79fb\u9664 NIC +message.action.delete.nic=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u79fb\u9664\u6b64 NIC\uff0c\u6b64\u64cd\u4f5c\u8fd8\u5c06\u4ece VM \u4e2d\u79fb\u9664\u5173\u8054\u7684\u7f51\u7edc\u3002 changed.item.properties=\u66f4\u6539\u9879\u76ee\u5c5e\u6027 -confirm.enable.s3=\u8bf7\u586b\u5199\u4e0b\u5217\u4fe1\u606f\u4ee5\u542f\u7528\u652f\u6301S3\u7684\u4e8c\u7ea7\u5b58\u50a8 +confirm.enable.s3=\u8bf7\u586b\u5199\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u542f\u7528\u5bf9 S3 \u652f\u6301\u7684\u8f85\u52a9\u5b58\u50a8\u7684\u652f\u6301 confirm.enable.swift=\u8bf7\u586b\u5199\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u542f\u7528\u5bf9 SWIFT \u7684\u652f\u6301 error.could.not.enable.zone=\u65e0\u6cd5\u542f\u7528\u533a\u57df error.installWizard.message=\u51fa\u73b0\u95ee\u9898\uff1b\u8bf7\u8fd4\u56de\u5e76\u66f4\u6b63\u4efb\u4f55\u9519\u8bef @@ -47,9 +52,10 @@ label.account.and.security.group=\u5e10\u6237\u3001\u5b89\u5168\u7ec4 label.account.id=\u5e10\u6237 ID label.account.name=\u5e10\u6237\u540d\u79f0 label.account.specific=\u5e10\u6237\u4e13\u7528 -label.accounts=\u5e10\u53f7 label.account=\u5e10\u6237 +label.accounts=\u5e10\u6237 label.acquire.new.ip=\u83b7\u53d6\u65b0 IP +label.acquire.new.secondary.ip=\u83b7\u53d6\u65b0\u8f85\u52a9 IP label.action.attach.disk.processing=\u6b63\u5728\u9644\u52a0\u78c1\u76d8... label.action.attach.disk=\u9644\u52a0\u78c1\u76d8 label.action.attach.iso.processing=\u6b63\u5728\u9644\u52a0 ISO... @@ -203,8 +209,8 @@ label.action.remove.host.processing=\u6b63\u5728\u5220\u9664\u4e3b\u673a... label.action.remove.host=\u5220\u9664\u4e3b\u673a label.action.reset.password.processing=\u6b63\u5728\u91cd\u7f6e\u5bc6\u7801... label.action.reset.password=\u91cd\u7f6e\u5bc6\u7801 -label.action.resize.volume.processing=Resizing Volume.... -label.action.resize.volume=Resize Volume +label.action.resize.volume.processing=\u6b63\u5728\u8c03\u6574\u5377\u5927\u5c0f.... +label.action.resize.volume=\u8c03\u6574\u5377\u5927\u5c0f label.action.resource.limits=\u8d44\u6e90\u9650\u5236 label.action.restore.instance.processing=\u6b63\u5728\u8fd8\u539f\u5b9e\u4f8b... label.action.restore.instance=\u8fd8\u539f\u5b9e\u4f8b @@ -220,7 +226,6 @@ label.action.stop.router.processing=\u6b63\u5728\u505c\u6b62\u8def\u7531\u5668.. label.action.stop.router=\u505c\u6b62\u8def\u7531\u5668 label.action.stop.systemvm.processing=\u6b63\u5728\u505c\u6b62\u7cfb\u7edf VM... label.action.stop.systemvm=\u505c\u6b62\u7cfb\u7edf VM -label.actions=\u64cd\u4f5c label.action.take.snapshot.processing=\u6b63\u5728\u521b\u5efa\u5feb\u7167... label.action.take.snapshot=\u521b\u5efa\u5feb\u7167 label.action.unmanage.cluster.processing=\u6b63\u5728\u53d6\u6d88\u6258\u7ba1\u7fa4\u96c6... @@ -229,17 +234,19 @@ label.action.update.OS.preference.processing=\u6b63\u5728\u66f4\u65b0\u64cd\u4f5 label.action.update.OS.preference=\u66f4\u65b0\u64cd\u4f5c\u7cfb\u7edf\u9996\u9009\u9879 label.action.update.resource.count.processing=\u6b63\u5728\u66f4\u65b0\u8d44\u6e90\u6570\u91cf... label.action.update.resource.count=\u66f4\u65b0\u8d44\u6e90\u6570\u91cf -label.action.vmsnapshot.create=\u6293\u53d6\u865a\u673a\u5feb\u7167 -label.action.vmsnapshot.delete=\u5220\u9664\u865a\u673a\u5feb\u7167 -label.action.vmsnapshot.revert=\u6062\u590d\u5230\u865a\u673a\u5feb\u7167 +label.action.vmsnapshot.create=\u521b\u5efa VM \u5feb\u7167 +label.action.vmsnapshot.delete=\u5220\u9664 VM \u5feb\u7167 +label.action.vmsnapshot.revert=\u8fd8\u539f\u5230 VM \u5feb\u7167 +label.actions=\u64cd\u4f5c label.activate.project=\u6fc0\u6d3b\u9879\u76ee label.active.sessions=\u6d3b\u52a8\u4f1a\u8bdd -label.add.accounts.to=\u6dfb\u52a0\u5e10\u6237\u81f3 -label.add.accounts=\u6dfb\u52a0\u5e10\u6237 label.add.account.to.project=\u5411\u9879\u76ee\u4e2d\u6dfb\u52a0\u5e10\u6237 label.add.account=\u6dfb\u52a0\u5e10\u6237 +label.add.accounts.to=\u6dfb\u52a0\u5e10\u6237\u81f3 +label.add.accounts=\u6dfb\u52a0\u5e10\u6237 label.add.ACL=\u6dfb\u52a0 ACL -label.add.BigSwitchVns.device=\u6dfb\u52a0BigSwitch Vns\u63a7\u5236\u5668 +label.add.affinity.group=\u6dfb\u52a0\u65b0\u5173\u8054\u6027\u7ec4 +label.add.BigSwitchVns.device=\u6dfb\u52a0 BigSwitch Vns \u63a7\u5236\u5668 label.add.by.cidr=\u6309 CIDR \u6dfb\u52a0 label.add.by.group=\u6309\u7ec4\u6dfb\u52a0 label.add.by=\u6dfb\u52a0\u65b9\u5f0f @@ -253,17 +260,8 @@ label.add.F5.device=\u6dfb\u52a0 F5 \u8bbe\u5907 label.add.firewall=\u6dfb\u52a0\u9632\u706b\u5899\u89c4\u5219 label.add.guest.network=\u6dfb\u52a0\u6765\u5bbe\u7f51\u7edc label.add.host=\u6dfb\u52a0\u4e3b\u673a -label.adding.cluster=\u6b63\u5728\u6dfb\u52a0\u7fa4\u96c6 -label.adding.failed=\u6dfb\u52a0\u5931\u8d25 -label.adding.pod=\u6b63\u5728\u6dfb\u52a0\u63d0\u4f9b\u70b9 -label.adding.processing=\u6b63\u5728\u6dfb\u52a0... label.add.ingress.rule=\u6dfb\u52a0\u5165\u53e3\u89c4\u5219 -label.adding.succeeded=\u5df2\u6210\u529f\u6dfb\u52a0 -label.adding=\u6b63\u5728\u6dfb\u52a0 -label.adding.user=\u6b63\u5728\u6dfb\u52a0\u7528\u6237 -label.adding.zone=\u6b63\u5728\u6dfb\u52a0\u533a\u57df label.add.ip.range=\u6dfb\u52a0 IP \u8303\u56f4 -label.additional.networks=\u5176\u4ed6\u7f51\u7edc label.add.load.balancer=\u6dfb\u52a0\u8d1f\u8f7d\u5e73\u8861\u5668 label.add.more=\u6dfb\u52a0\u66f4\u591a label.add.netScaler.device=\u6dfb\u52a0 Netscaler \u8bbe\u5907 @@ -276,7 +274,7 @@ label.add.new.gateway=\u6dfb\u52a0\u65b0\u7f51\u5173 label.add.new.NetScaler=\u6dfb\u52a0\u65b0 NetScaler label.add.new.SRX=\u6dfb\u52a0\u65b0 SRX label.add.new.tier=\u6dfb\u52a0\u65b0\u5c42 -label.add.NiciraNvp.device=\u6dfb\u52a0Nvp\u63a7\u5236\u5668 +label.add.NiciraNvp.device=\u6dfb\u52a0 Nvp \u63a7\u5236\u5668 label.add.physical.network=\u6dfb\u52a0\u7269\u7406\u7f51\u7edc label.add.pod=\u6dfb\u52a0\u63d0\u4f9b\u70b9 label.add.port.forwarding.rule=\u6dfb\u52a0\u7aef\u53e3\u8f6c\u53d1\u89c4\u5219 @@ -294,24 +292,36 @@ label.add.static.route=\u6dfb\u52a0\u9759\u6001\u8def\u7531 label.add.system.service.offering=\u6dfb\u52a0\u7cfb\u7edf\u670d\u52a1\u65b9\u6848 label.add.template=\u6dfb\u52a0\u6a21\u677f label.add.to.group=\u6dfb\u52a0\u5230\u7ec4 -label.add=\u6dfb\u52a0 label.add.user=\u6dfb\u52a0\u7528\u6237 label.add.vlan=\u6dfb\u52a0 VLAN -label.add.vms.to.lb=\u5411\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219\u4e2d\u6dfb\u52a0 VM -label.add.vms=\u6dfb\u52a0 VM label.add.VM.to.tier=\u5411\u5c42\u4e2d\u6dfb\u52a0 VM label.add.vm=\u6dfb\u52a0 VM +label.add.vms.to.lb=\u5411\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219\u4e2d\u6dfb\u52a0 VM +label.add.vms=\u6dfb\u52a0 VM label.add.volume=\u6dfb\u52a0\u5377 label.add.vpc=\u6dfb\u52a0 VPC label.add.vpn.customer.gateway=\u6dfb\u52a0 VPN \u5ba2\u6237\u7f51\u5173 label.add.VPN.gateway=\u6dfb\u52a0 VPN \u7f51\u5173 label.add.vpn.user=\u6dfb\u52a0 VPN \u7528\u6237 label.add.zone=\u6dfb\u52a0\u533a\u57df +label.add=\u6dfb\u52a0 +label.adding.cluster=\u6b63\u5728\u6dfb\u52a0\u7fa4\u96c6 +label.adding.failed=\u6dfb\u52a0\u5931\u8d25 +label.adding.pod=\u6b63\u5728\u6dfb\u52a0\u63d0\u4f9b\u70b9 +label.adding.processing=\u6b63\u5728\u6dfb\u52a0... +label.adding.succeeded=\u5df2\u6210\u529f\u6dfb\u52a0 +label.adding.user=\u6b63\u5728\u6dfb\u52a0\u7528\u6237 +label.adding.zone=\u6b63\u5728\u6dfb\u52a0\u533a\u57df +label.adding=\u6b63\u5728\u6dfb\u52a0 +label.additional.networks=\u5176\u4ed6\u7f51\u7edc label.admin.accounts=\u7ba1\u7406\u5458\u5e10\u6237 label.admin=\u7ba1\u7406\u5458 label.advanced.mode=\u9ad8\u7ea7\u6a21\u5f0f label.advanced.search=\u9ad8\u7ea7\u641c\u7d22 label.advanced=\u9ad8\u7ea7 +label.affinity.group=\u5173\u8054\u6027\u7ec4 +label.affinity.groups=\u5173\u8054\u6027\u7ec4 +label.affinity=\u5173\u8054\u6027 label.agent.password=\u4ee3\u7406\u5bc6\u7801 label.agent.username=\u4ee3\u7406\u7528\u6237\u540d label.agree=\u540c\u610f @@ -319,6 +329,9 @@ label.alert=\u8b66\u62a5 label.algorithm=\u7b97\u6cd5 label.allocated=\u5df2\u5206\u914d label.allocation.state=\u5206\u914d\u72b6\u6001 +label.anti.affinity.group=\u53cd\u5173\u8054\u6027\u7ec4 +label.anti.affinity.groups=\u53cd\u5173\u8054\u6027\u7ec4 +label.anti.affinity=\u53cd\u5173\u8054\u6027 label.api.key=API \u5bc6\u94a5 label.apply=\u5e94\u7528 label.assign.to.load.balancer=\u6b63\u5728\u5c06\u5b9e\u4f8b\u5206\u914d\u7ed9\u8d1f\u8f7d\u5e73\u8861\u5668 @@ -326,10 +339,10 @@ label.assign=\u5206\u914d label.associated.network.id=\u5df2\u5173\u8054\u7f51\u7edc ID label.associated.network=\u5173\u8054\u7f51\u7edc label.attached.iso=\u5df2\u9644\u52a0 ISO -label.author.email=\u4f5c\u8005\u90ae\u7bb1 +label.author.email=\u4f5c\u8005\u7535\u5b50\u90ae\u4ef6 label.author.name=\u4f5c\u8005\u59d3\u540d -label.availability=\u53ef\u7528\u6027 label.availability.zone=\u53ef\u7528\u533a\u57df +label.availability=\u53ef\u7528\u6027 label.available.public.ips=\u53ef\u7528\u516c\u7528 IP \u5730\u5740 label.available=\u53ef\u7528 label.back=\u8fd4\u56de @@ -340,7 +353,7 @@ label.bigswitch.controller.address=BigSwitch Vns \u63a7\u5236\u5668\u5730\u5740 label.bootable=\u53ef\u542f\u52a8 label.broadcast.domain.range=\u5e7f\u64ad\u57df\u8303\u56f4 label.broadcast.domain.type=\u5e7f\u64ad\u57df\u7c7b\u578b -label.broadcast.uri=\u5e7f\u64adURI +label.broadcast.uri=\u5e7f\u64ad URI label.by.account=\u6309\u5e10\u6237 label.by.availability=\u6309\u53ef\u7528\u6027 label.by.domain=\u6309\u57df @@ -350,12 +363,12 @@ label.by.pod=\u6309\u63d0\u4f9b\u70b9 label.by.role=\u6309\u89d2\u8272 label.by.start.date=\u6309\u5f00\u59cb\u65e5\u671f label.by.state=\u6309\u72b6\u6001 -label.bytes.received=\u63a5\u6536\u7684\u5b57\u8282\u6570 -label.bytes.sent=\u53d1\u9001\u7684\u5b57\u8282\u6570 label.by.traffic.type=\u6309\u6d41\u91cf\u7c7b\u578b label.by.type.id=\u6309\u7c7b\u578b ID label.by.type=\u6309\u7c7b\u578b label.by.zone=\u6309\u533a\u57df +label.bytes.received=\u63a5\u6536\u7684\u5b57\u8282\u6570 +label.bytes.sent=\u53d1\u9001\u7684\u5b57\u8282\u6570 label.cancel=\u53d6\u6d88 label.capacity=\u5bb9\u91cf label.certificate=\u8bc1\u4e66 @@ -364,32 +377,32 @@ label.change.value=\u66f4\u6539\u503c label.character=\u5b57\u7b26 label.checksum=MD5 \u6821\u9a8c\u548c label.cidr.account=CIDR \u6216\u5e10\u6237/\u5b89\u5168\u7ec4 -label.cidr=CIDR label.CIDR.list=CIDR \u5217\u8868 label.cidr.list=\u6e90 CIDR label.CIDR.of.destination.network=\u76ee\u7684\u5730\u7f51\u7edc\u7684 CIDR +label.cidr=CIDR label.clean.up=\u6e05\u9664 label.clear.list=\u6e05\u9664\u5217\u8868 label.close=\u5173\u95ed label.cloud.console=\u4e91\u7ba1\u7406\u63a7\u5236\u53f0 label.cloud.managed=\u7531 Cloud.com \u7ba1\u7406 label.cluster.name=\u7fa4\u96c6\u540d\u79f0 -label.clusters=\u7fa4\u96c6 label.cluster.type=\u7fa4\u96c6\u7c7b\u578b label.cluster=\u7fa4\u96c6 +label.clusters=\u7fa4\u96c6 label.clvm=CLVM label.code=\u4ee3\u7801 label.community=\u793e\u533a label.compute.and.storage=\u8ba1\u7b97\u4e0e\u5b58\u50a8 -label.compute.offerings=\u8ba1\u7b97\u65b9\u6848 label.compute.offering=\u8ba1\u7b97\u65b9\u6848 +label.compute.offerings=\u8ba1\u7b97\u65b9\u6848 label.compute=\u8ba1\u7b97 -label.configuration=\u4e91\u5e73\u53f0\u914d\u7f6e +label.configuration=\u914d\u7f6e label.configure.network.ACLs=\u914d\u7f6e\u7f51\u7edc ACL -label.configure=\u914d\u7f6e label.configure.vpc=\u914d\u7f6e VPC -label.confirmation=\u786e\u8ba4 +label.configure=\u914d\u7f6e label.confirm.password=\u786e\u8ba4\u5bc6\u7801 +label.confirmation=\u786e\u8ba4 label.congratulations=\u795d\u8d3a\u60a8\! label.conserve.mode=\u4fdd\u62a4\u6a21\u5f0f label.console.proxy=\u63a7\u5236\u53f0\u4ee3\u7406 @@ -399,15 +412,15 @@ label.corrections.saved=\u5df2\u4fdd\u5b58\u4fee\u6b63 label.cpu.allocated.for.VMs=\u5df2\u5206\u914d\u7ed9 VM \u7684 CPU label.cpu.allocated=\u5df2\u5206\u914d\u7684 CPU label.CPU.cap=CPU \u4e0a\u9650 -label.cpu=CPU -label.cpu.limits=CPU\u9650\u5236 +label.cpu.limits=CPU \u9650\u5236 label.cpu.mhz=CPU (MHz) label.cpu.utilized=CPU \u5229\u7528\u7387 -label.created.by.system=\u7531\u7cfb\u7edf\u521b\u5efa -label.created=\u521b\u5efa\u65e5\u671f +label.cpu=CPU label.create.project=\u521b\u5efa\u9879\u76ee label.create.template=\u521b\u5efa\u6a21\u677f label.create.VPN.connection=\u521b\u5efa VPN \u8fde\u63a5 +label.created.by.system=\u7531\u7cfb\u7edf\u521b\u5efa +label.created=\u521b\u5efa\u65e5\u671f label.cross.zones=\u8de8\u533a\u57df label.custom.disk.size=\u81ea\u5b9a\u4e49\u78c1\u76d8\u5927\u5c0f label.daily=\u6bcf\u5929\u4e00\u6b21 @@ -418,51 +431,56 @@ label.day.of.week=\u661f\u671f label.dead.peer.detection=\u5931\u6548\u5bf9\u7b49\u4f53\u68c0\u6d4b label.decline.invitation=\u62d2\u7edd\u9080\u8bf7 label.dedicated=\u4e13\u7528 -label.default=\u9ed8\u8ba4\u503c label.default.use=\u9ed8\u8ba4\u4f7f\u7528 label.default.view=\u9ed8\u8ba4\u89c6\u56fe -label.delete.BigSwitchVns=\u79fb\u9664BigSwitch Vns\u63a7\u5236\u5668 +label.default=\u9ed8\u8ba4\u503c +label.delete.affinity.group=\u5220\u9664\u5173\u8054\u6027\u7ec4 +label.delete.BigSwitchVns=\u79fb\u9664 BigSwitch Vns \u63a7\u5236\u5668 label.delete.F5=\u5220\u9664 F5 label.delete.gateway=\u5220\u9664\u7f51\u5173 label.delete.NetScaler=\u5220\u9664 NetScaler -label.delete.NiciraNvp=\u5220\u9664Nvp\u63a7\u5236\u5668 +label.delete.NiciraNvp=\u79fb\u9664 Nvp \u63a7\u5236\u5668 label.delete.project=\u5220\u9664\u9879\u76ee label.delete.SRX=\u5220\u9664 SRX -label.delete=\u5220\u9664 label.delete.VPN.connection=\u5220\u9664 VPN \u8fde\u63a5 label.delete.VPN.customer.gateway=\u5220\u9664 VPN \u5ba2\u6237\u7f51\u5173 label.delete.VPN.gateway=\u5220\u9664 VPN \u7f51\u5173 label.delete.vpn.user=\u5220\u9664 VPN \u7528\u6237 +label.delete=\u5220\u9664 label.deleting.failed=\u5220\u9664\u5931\u8d25 label.deleting.processing=\u6b63\u5728\u5220\u9664... label.description=\u8bf4\u660e label.destination.physical.network.id=\u76ee\u6807\u7269\u7406\u7f51\u7edc ID label.destination.zone=\u76ee\u6807\u533a\u57df label.destroy.router=\u9500\u6bc1\u8def\u7531\u5668 -label.destroy=\u00e9\u0094\u0080\u00e6\u00af\u0081 +label.destroy=\u9500\u6bc1 label.detaching.disk=\u6b63\u5728\u53d6\u6d88\u9644\u52a0\u78c1\u76d8 label.details=\u8be6\u7ec6\u4fe1\u606f label.device.id=\u8bbe\u5907 ID label.devices=\u8bbe\u5907 -label.dhcp=DHCP label.DHCP.server.type=DHCP \u670d\u52a1\u5668\u7c7b\u578b -label.direct.ips=\u76f4\u63a5 IP -label.disabled=\u5df2\u7981\u7528 +label.dhcp=DHCP +label.direct.ips=\u5171\u4eab\u7f51\u7edc IP label.disable.provider=\u7981\u7528\u63d0\u4f9b\u7a0b\u5e8f label.disable.vpn=\u7981\u7528 VPN +label.disabled=\u5df2\u7981\u7528 label.disabling.vpn.access=\u6b63\u5728\u7981\u7528 VPN \u8bbf\u95ee label.disk.allocated=\u5df2\u5206\u914d\u7684\u78c1\u76d8 label.disk.offering=\u78c1\u76d8\u65b9\u6848 +label.disk.read.bytes=\u78c1\u76d8\u8bfb\u53d6(\u5b57\u8282) +label.disk.read.io=\u78c1\u76d8\u8bfb\u53d6(IO) label.disk.size.gb=\u78c1\u76d8\u5927\u5c0f(GB) label.disk.size=\u78c1\u76d8\u5927\u5c0f label.disk.total=\u78c1\u76d8\u603b\u91cf label.disk.volume=\u78c1\u76d8\u5377 +label.disk.write.bytes=\u78c1\u76d8\u5199\u5165(\u5b57\u8282) +label.disk.write.io=\u78c1\u76d8\u5199\u5165(IO) label.display.name=\u663e\u793a\u540d\u79f0 label.display.text=\u663e\u793a\u6587\u672c label.dns.1=DNS 1 label.dns.2=DNS 2 -label.dns=DNS label.DNS.domain.for.guest.networks=\u6765\u5bbe\u7f51\u7edc\u7684 DNS \u57df +label.dns=DNS label.domain.admin=\u57df\u7ba1\u7406\u5458 label.domain.id=\u57df ID label.domain.name=\u57df\u540d @@ -473,31 +491,32 @@ label.done=\u5b8c\u6210 label.double.quotes.are.not.allowed=\u4e0d\u5141\u8bb8\u4f7f\u7528\u53cc\u5f15\u53f7 label.download.progress=\u4e0b\u8f7d\u8fdb\u5ea6 label.drag.new.position=\u62d6\u52a8\u5230\u65b0\u4f4d\u7f6e +label.edit.affinity.group=\u7f16\u8f91\u5173\u8054\u6027\u7ec4 label.edit.lb.rule=\u7f16\u8f91\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219 label.edit.network.details=\u7f16\u8f91\u7f51\u7edc\u8be6\u60c5 label.edit.project.details=\u7f16\u8f91\u9879\u76ee\u8be6\u60c5 label.edit.tags=\u7f16\u8f91\u6807\u7b7e label.edit.traffic.type=\u7f16\u8f91\u6d41\u91cf\u7c7b\u578b -label.edit=\u7f16\u8f91 label.edit.vpc=\u7f16\u8f91 VPC -label.egress.rules=\u51fa\u53e3\u89c4\u5219 +label.edit=\u7f16\u8f91 label.egress.rule=\u51fa\u53e3\u89c4\u5219 +label.egress.rules=\u51fa\u53e3\u89c4\u5219 label.elastic.IP=\u5f39\u6027 IP label.elastic.LB=\u5f39\u6027\u8d1f\u8f7d\u5e73\u8861\u5668 label.elastic=\u5f39\u6027 label.email=\u7535\u5b50\u90ae\u4ef6 label.enable.provider=\u542f\u7528\u63d0\u4f9b\u7a0b\u5e8f -label.enable.s3=\u542f\u7528\u652f\u6301S3\u7684\u4e8c\u7ea7\u5b58\u50a8 +label.enable.s3=\u542f\u7528 S3 \u652f\u6301\u7684\u8f85\u52a9\u5b58\u50a8 label.enable.swift=\u542f\u7528 SWIFT label.enable.vpn=\u542f\u7528 VPN label.enabling.vpn.access=\u6b63\u5728\u542f\u7528 VPN \u8bbf\u95ee label.enabling.vpn=\u6b63\u5728\u542f\u7528 VPN label.end.IP=\u7ed3\u675f IP -label.endpoint.or.operation=\u7aef\u70b9\u6216\u64cd\u4f5c -label.endpoint=\u7aef\u70b9 label.end.port=\u7ed3\u675f\u7aef\u53e3 label.end.reserved.system.IP=\u7ed3\u675f\u9884\u7559\u7cfb\u7edf IP label.end.vlan=\u7ed3\u675f VLAN +label.endpoint.or.operation=\u7aef\u70b9\u6216\u64cd\u4f5c +label.endpoint=\u7aef\u70b9 label.enter.token=\u8f93\u5165\u4ee4\u724c label.error.code=\u9519\u8bef\u4ee3\u7801 label.error=\u9519\u8bef @@ -546,14 +565,14 @@ label.hints=\u63d0\u793a label.host.alerts=\u4e3b\u673a\u8b66\u62a5 label.host.MAC=\u4e3b\u673a MAC label.host.name=\u4e3b\u673a\u540d\u79f0 -label.hosts=\u4e3b\u673a label.host.tags=\u4e3b\u673a\u6807\u7b7e label.host=\u4e3b\u673a +label.hosts=\u4e3b\u673a label.hourly=\u6bcf\u5c0f\u65f6\u4e00\u6b21 label.hypervisor.capabilities=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u529f\u80fd label.hypervisor.type=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u7c7b\u578b -label.hypervisor=\u865a\u62df\u673a\u5e73\u53f0 label.hypervisor.version=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u7248\u672c +label.hypervisor=\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f label.id=ID label.IKE.DH=IKE DH \u7b97\u6cd5 label.IKE.encryption=IKE \u52a0\u5bc6\u7b97\u6cd5 @@ -573,16 +592,16 @@ label.installWizard.addPrimaryStorageIntro.subtitle=\u4ec0\u4e48\u662f\u4e3b\u5b label.installWizard.addPrimaryStorageIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u4e3b\u5b58\u50a8 label.installWizard.addSecondaryStorageIntro.subtitle=\u4ec0\u4e48\u662f\u8f85\u52a9\u5b58\u50a8? label.installWizard.addSecondaryStorageIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u8f85\u52a9\u5b58\u50a8 +label.installWizard.addZone.title=\u6dfb\u52a0\u533a\u57df label.installWizard.addZoneIntro.subtitle=\u4ec0\u4e48\u662f\u533a\u57df? label.installWizard.addZoneIntro.title=\u6dfb\u52a0\u4e00\u4e2a\u533a\u57df -label.installWizard.addZone.title=\u6dfb\u52a0\u533a\u57df label.installWizard.click.launch=\u8bf7\u5355\u51fb\u201c\u542f\u52a8\u201d\u6309\u94ae\u3002 label.installWizard.subtitle=\u6b64\u6559\u7a0b\u5c06\u5e2e\u52a9\u60a8\u8bbe\u7f6e CloudStack&\#8482 \u5b89\u88c5 label.installWizard.title=\u60a8\u597d\uff0c\u6b22\u8fce\u4f7f\u7528 CloudStack&\#8482 label.instance.limits=\u5b9e\u4f8b\u9650\u5236 label.instance.name=\u5b9e\u4f8b\u540d\u79f0 -label.instances=\u5b9e\u4f8b label.instance=\u5b9e\u4f8b +label.instances=\u5b9e\u4f8b label.internal.dns.1=\u5185\u90e8 DNS 1 label.internal.dns.2=\u5185\u90e8 DNS 2 label.internal.name=\u5185\u90e8\u540d\u79f0 @@ -591,38 +610,38 @@ label.introduction.to.cloudstack=CloudStack&\#8482 \u7b80\u4ecb label.invalid.integer=\u65e0\u6548\u6574\u6570 label.invalid.number=\u65e0\u6548\u6570\u5b57 label.invitations=\u9080\u8bf7 -label.invited.accounts=\u5df2\u9080\u8bf7\u7684\u5e10\u6237 label.invite.to=\u9080\u8bf7\u52a0\u5165 label.invite=\u9080\u8bf7 +label.invited.accounts=\u5df2\u9080\u8bf7\u7684\u5e10\u6237 label.ip.address=IP \u5730\u5740 -label.ipaddress=IP \u5730\u5740 label.ip.allocations=IP \u5206\u914d -label.ip=IP label.ip.limits=\u516c\u7528 IP \u9650\u5236 label.ip.or.fqdn=IP \u6216 FQDN label.ip.range=IP \u8303\u56f4 label.ip.ranges=IP \u8303\u56f4 -label.IPsec.preshared.key=IPsec \u9884\u5171\u4eab\u5bc6\u94a5 +label.ip=IP +label.ipaddress=IP \u5730\u5740 label.ips=IP -label.iscsi=iSCSI +label.IPsec.preshared.key=IPsec \u9884\u5171\u4eab\u5bc6\u94a5 label.is.default=\u662f\u5426\u4e3a\u9ed8\u8ba4\u503c +label.is.redundant.router=\u5197\u4f59 +label.is.shared=\u662f\u5426\u5171\u4eab +label.is.system=\u662f\u5426\u4e3a\u7cfb\u7edf +label.iscsi=iSCSI label.iso.boot=ISO \u542f\u52a8 label.iso=ISO label.isolated.networks=\u9694\u79bb\u7f51\u7edc label.isolation.method=\u9694\u79bb\u65b9\u6cd5 label.isolation.mode=\u9694\u79bb\u6a21\u5f0f -label.isolation.uri=\u9694\u79bbURI -label.is.redundant.router=\u5197\u4f59 -label.is.shared=\u662f\u5426\u5171\u4eab -label.is.system=\u662f\u5426\u4e3a\u7cfb\u7edf +label.isolation.uri=\u9694\u79bb URI label.item.listing=\u9879\u76ee\u5217\u8868 label.keep=\u4fdd\u7559 -label.keyboard.type=\u952e\u76d8\u7c7b\u578b label.key=\u5bc6\u94a5 +label.keyboard.type=\u952e\u76d8\u7c7b\u578b label.kvm.traffic.label=KVM \u6d41\u91cf\u6807\u7b7e label.label=\u6807\u7b7e label.lang.arabic=\u963f\u62c9\u4f2f\u8bed -label.lang.brportugese=\u5df4\u897f\u8461\u8404\u7259\u8bed +label.lang.brportugese=\u8461\u8404\u7259\u8bed(\u5df4\u897f) label.lang.catalan=\u52a0\u6cf0\u7f57\u5c3c\u4e9a\u8bed label.lang.chinese=\u7b80\u4f53\u4e2d\u6587 label.lang.english=\u82f1\u8bed @@ -630,16 +649,16 @@ label.lang.french=\u6cd5\u8bed label.lang.german=\u5fb7\u8bed label.lang.italian=\u610f\u5927\u5229\u8bed label.lang.japanese=\u65e5\u8bed -label.lang.korean=\u97e9\u56fd\u8bed +label.lang.korean=\u97e9\u8bed label.lang.norwegian=\u632a\u5a01\u8bed label.lang.russian=\u4fc4\u8bed label.lang.spanish=\u897f\u73ed\u7259\u8bed label.last.disconnected=\u4e0a\u6b21\u65ad\u5f00\u8fde\u63a5\u65f6\u95f4 label.last.name=\u59d3\u6c0f label.latest.events=\u6700\u65b0\u4e8b\u4ef6 -label.launch=\u542f\u52a8 label.launch.vm=\u542f\u52a8 VM label.launch.zone=\u542f\u52a8\u533a\u57df +label.launch=\u542f\u52a8 label.LB.isolation=\u8d1f\u8f7d\u5e73\u8861\u5668\u9694\u79bb label.least.connections=\u6700\u5c11\u8fde\u63a5\u7b97\u6cd5 label.level=\u7ea7\u522b @@ -653,40 +672,40 @@ label.local.storage=\u672c\u5730\u5b58\u50a8 label.local=\u672c\u5730 label.login=\u767b\u5f55 label.logout=\u6ce8\u9500 -label.lun=LUN label.LUN.number=LUN \u53f7 +label.lun=LUN label.make.project.owner=\u8bbe\u4e3a\u5e10\u6237\u9879\u76ee\u6240\u6709\u8005 -label.management.ips=\u7ba1\u7406\u7c7b IP \u5730\u5740 -label.management=\u7ba1\u7406 label.manage.resources=\u7ba1\u7406\u8d44\u6e90 label.manage=\u6258\u7ba1 -label.max.cpus=\u6700\u5927CPU\u6838\u5fc3\u6570 +label.management.ips=\u7ba1\u7406\u7c7b IP \u5730\u5740 +label.management=\u7ba1\u7406 +label.max.cpus=\u6700\u5927 CPU \u5185\u6838\u6570 label.max.guest.limit=\u6700\u5927\u6765\u5bbe\u6570\u9650\u5236 -label.maximum=\u6700\u5927\u503c -label.max.memory=\u6700\u5927\u5185\u5b58\u6570(\u5146\u5b57\u8282) +label.max.memory=\u6700\u5927\u5185\u5b58(MiB) label.max.networks=\u6700\u5927\u7f51\u7edc\u6570 -label.max.primary.storage=\u6700\u5927\u4e3b\u5b58\u50a8(G\u5b57\u8282) +label.max.primary.storage=\u6700\u5927\u4e3b\u5b58\u50a8(GiB) label.max.public.ips=\u6700\u5927\u516c\u7528 IP \u6570 -label.max.secondary.storage=\u6700\u5927\u4e8c\u7ea7\u5b58\u50a8(G\u5b57\u8282) +label.max.secondary.storage=\u6700\u5927\u8f85\u52a9\u5b58\u50a8(GiB) label.max.snapshots=\u6700\u5927\u5feb\u7167\u6570 label.max.templates=\u6700\u5927\u6a21\u677f\u6570 label.max.vms=\u6700\u5927\u7528\u6237 VM \u6570 label.max.volumes=\u6700\u5927\u5377\u6570 -label.max.vpcs=\u6700\u591aVPC\u5c42\u6570 +label.max.vpcs=\u6700\u5927 VPC \u6570 +label.maximum=\u6700\u5927\u503c label.may.continue=\u60a8\u73b0\u5728\u53ef\u4ee5\u7ee7\u7eed\u8fdb\u884c\u64cd\u4f5c\u3002 label.memory.allocated=\u5df2\u5206\u914d\u7684\u5185\u5b58 -label.memory.limits=\u5185\u5b58\u9650\u5236(\u5146\u5b57\u8282) +label.memory.limits=\u5185\u5b58\u9650\u5236(MiB) label.memory.mb=\u5185\u5b58(MB) label.memory.total=\u5185\u5b58\u603b\u91cf -label.memory=\u5185\u5b58 label.memory.used=\u5df2\u4f7f\u7528\u7684\u5185\u5b58 -label.menu.accounts=\u5e10\u53f7 +label.memory=\u5185\u5b58 +label.menu.accounts=\u5e10\u6237 label.menu.alerts=\u8b66\u62a5 label.menu.all.accounts=\u6240\u6709\u5e10\u6237 label.menu.all.instances=\u6240\u6709\u5b9e\u4f8b label.menu.community.isos=\u793e\u533a ISO label.menu.community.templates=\u793e\u533a\u6a21\u677f -label.menu.configuration=\u4e91\u5e73\u53f0\u914d\u7f6e +label.menu.configuration=\u914d\u7f6e label.menu.dashboard=\u63a7\u5236\u677f label.menu.destroyed.instances=\u5df2\u9500\u6bc1\u7684\u5b9e\u4f8b label.menu.disk.offerings=\u78c1\u76d8\u65b9\u6848 @@ -697,7 +716,7 @@ label.menu.featured.templates=\u7cbe\u9009\u6a21\u677f label.menu.global.settings=\u5168\u5c40\u8bbe\u7f6e label.menu.infrastructure=\u57fa\u7840\u67b6\u6784 label.menu.instances=\u5b9e\u4f8b -label.menu.ipaddresses=IP\u5730\u5740 +label.menu.ipaddresses=IP \u5730\u5740 label.menu.isos=ISO label.menu.my.accounts=\u6211\u7684\u5e10\u6237 label.menu.my.instances=\u6211\u7684\u5b9e\u4f8b @@ -708,14 +727,14 @@ label.menu.network=\u7f51\u7edc label.menu.physical.resources=\u7269\u7406\u8d44\u6e90 label.menu.regions=\u533a\u57df label.menu.running.instances=\u6b63\u5728\u8fd0\u884c\u7684\u5b9e\u4f8b -label.menu.security.groups=\u5b89\u5168\u5206\u7ec4 -label.menu.service.offerings=\u670d\u52a1\u63d0\u4f9b +label.menu.security.groups=\u5b89\u5168\u7ec4 +label.menu.service.offerings=\u670d\u52a1\u65b9\u6848 label.menu.snapshots=\u5feb\u7167 label.menu.stopped.instances=\u5df2\u505c\u6b62\u7684\u5b9e\u4f8b label.menu.storage=\u5b58\u50a8 label.menu.system.service.offerings=\u7cfb\u7edf\u65b9\u6848 -label.menu.system=\u7cfb\u7edf label.menu.system.vms=\u7cfb\u7edf VM +label.menu.system=\u7cfb\u7edf label.menu.templates=\u6a21\u677f label.menu.virtual.appliances=\u865a\u62df\u8bbe\u5907 label.menu.virtual.resources=\u865a\u62df\u8d44\u6e90 @@ -745,16 +764,15 @@ label.name=\u540d\u79f0 label.nat.port.range=NAT \u7aef\u53e3\u8303\u56f4 label.netmask=\u7f51\u7edc\u63a9\u7801 label.netScaler=NetScaler -label.network.ACLs=\u7f51\u7edc ACL label.network.ACL.total=\u7f51\u7edc ACL \u603b\u6570 label.network.ACL=\u7f51\u7edc ACL +label.network.ACLs=\u7f51\u7edc ACL label.network.desc=\u7f51\u7edc\u63cf\u8ff0 label.network.device.type=\u7f51\u7edc\u8bbe\u5907\u7c7b\u578b label.network.device=\u7f51\u7edc\u8bbe\u5907 label.network.domain.text=\u7f51\u7edc\u57df label.network.domain=\u7f51\u7edc\u57df label.network.id=\u7f51\u7edc ID -label.networking.and.security=\u7f51\u7edc\u8fde\u63a5\u4e0e\u5b89\u5168 label.network.label.display.for.blank.value=\u4f7f\u7528\u9ed8\u8ba4\u7f51\u5173 label.network.name=\u7f51\u7edc\u540d\u79f0 label.network.offering.display.text=\u7f51\u7edc\u65b9\u6848\u663e\u793a\u6587\u672c @@ -764,24 +782,25 @@ label.network.offering=\u7f51\u7edc\u65b9\u6848 label.network.rate.megabytes=\u7f51\u7edc\u901f\u7387(MB/\u79d2) label.network.rate=\u7f51\u7edc\u901f\u7387 label.network.read=\u7f51\u7edc\u8bfb\u53d6\u91cf -label.network.service.providers=\u7f51\u7edc\u670d\u52a1\u63d0\u4f9b\u65b9\u6848 -label.networks=\u7f51\u7edc +label.network.service.providers=\u7f51\u7edc\u670d\u52a1\u63d0\u4f9b\u7a0b\u5e8f label.network.type=\u7f51\u7edc\u7c7b\u578b -label.network=\u7f51\u7edc label.network.write=\u7f51\u7edc\u5199\u5165\u91cf +label.network=\u7f51\u7edc +label.networking.and.security=\u7f51\u7edc\u8fde\u63a5\u4e0e\u5b89\u5168 +label.networks=\u7f51\u7edc label.new.password=\u65b0\u5bc6\u7801 label.new.project=\u65b0\u5efa\u9879\u76ee -label.new=\u65b0\u5efa label.new.vm=\u65b0\u5efa VM +label.new=\u65b0\u5efa label.next=\u4e0b\u4e00\u6b65 label.nexusVswitch=Nexus 1000v -label.nfs=NFS label.nfs.server=NFS \u670d\u52a1\u5668 label.nfs.storage=NFS \u5b58\u50a8 +label.nfs=NFS label.nic.adapter.type=NIC \u9002\u914d\u5668\u7c7b\u578b label.nicira.controller.address=\u63a7\u5236\u5668\u5730\u5740 -label.nicira.l3gatewayserviceuuid=3\u5c42\u7f51\u5173\u670d\u52a1UUID -label.nicira.transportzoneuuid=\u4f20\u8f93\u8d44\u6e90\u57dfUUID +label.nicira.l3gatewayserviceuuid=L3 Gateway Service UUID +label.nicira.transportzoneuuid=\u4f20\u8f93\u533a\u57df UUID label.nics=NIC label.no.actions=\u65e0\u53ef\u7528\u64cd\u4f5c label.no.alerts=\u65e0\u6700\u8fd1\u53d1\u51fa\u7684\u8b66\u62a5 @@ -789,24 +808,24 @@ label.no.data=\u65e0\u53ef\u663e\u793a\u7684\u6570\u636e label.no.errors=\u65e0\u6700\u8fd1\u51fa\u73b0\u7684\u9519\u8bef label.no.isos=\u65e0\u53ef\u7528 ISO label.no.items=\u65e0\u53ef\u7528\u9879\u76ee -label.none=\u65e0 label.no.security.groups=\u65e0\u53ef\u7528\u5b89\u5168\u7ec4 -label.not.found=\u672a\u627e\u5230 label.no.thanks=\u4e0d\uff0c\u8c22\u8c22 -label.notifications=\u901a\u77e5 label.no=\u5426 +label.none=\u65e0 +label.not.found=\u672a\u627e\u5230 +label.notifications=\u901a\u77e5 +label.num.cpu.cores=CPU \u5185\u6838\u6570 label.number.of.clusters=\u7fa4\u96c6\u6570\u91cf label.number.of.hosts=\u4e3b\u673a\u6570\u91cf label.number.of.pods=\u63d0\u4f9b\u70b9\u6570\u91cf label.number.of.system.vms=\u7cfb\u7edf VM \u6570 label.number.of.virtual.routers=\u865a\u62df\u8def\u7531\u5668\u6570 label.number.of.zones=\u533a\u57df\u6570\u91cf -label.num.cpu.cores=CPU \u5185\u6838\u6570 label.numretries=\u91cd\u8bd5\u6b21\u6570 label.ocfs2=OCFS2 label.offer.ha=\u63d0\u4f9b\u9ad8\u53ef\u7528\u6027 label.ok=\u786e\u5b9a -label.optional=\u53ef\u9009\u7684 +label.optional=\u53ef\u9009 label.order=\u6392\u5e8f label.os.preference=\u64cd\u4f5c\u7cfb\u7edf\u9996\u9009\u9879 label.os.type=\u64cd\u4f5c\u7cfb\u7edf\u7c7b\u578b @@ -829,50 +848,50 @@ label.please.wait=\u8bf7\u7a0d\u5019 label.plugin.details=\u63d2\u4ef6\u8be6\u7ec6\u4fe1\u606f label.plugins=\u63d2\u4ef6 label.pod.name=\u63d0\u4f9b\u70b9\u540d\u79f0 -label.pods=\u63d0\u4f9b\u70b9 label.pod=\u63d0\u4f9b\u70b9 +label.pods=\u63d0\u4f9b\u70b9 label.port.forwarding.policies=\u7aef\u53e3\u8f6c\u53d1\u7b56\u7565 label.port.forwarding=\u7aef\u53e3\u8f6c\u53d1 label.port.range=\u7aef\u53e3\u8303\u56f4 label.PreSetup=PreSetup -label.previous=\u4e0a\u4e00\u6b65 label.prev=\u4e0a\u4e00\u9875 +label.previous=\u4e0a\u4e00\u6b65 label.primary.allocated=\u5df2\u5206\u914d\u7684\u4e3b\u5b58\u50a8 label.primary.network=\u4e3b\u7f51\u7edc label.primary.storage.count=\u4e3b\u5b58\u50a8\u6c60 -label.primary.storage.limits=\u4e3b\u5b58\u50a8\u9650\u5236(G\u5b57\u8282) +label.primary.storage.limits=\u4e3b\u5b58\u50a8\u9650\u5236(GiB) label.primary.storage=\u4e3b\u5b58\u50a8 label.primary.used=\u5df2\u4f7f\u7528\u7684\u4e3b\u5b58\u50a8 label.private.Gateway=\u4e13\u7528\u7f51\u5173 label.private.interface=\u4e13\u7528\u63a5\u53e3 label.private.ip.range=\u4e13\u7528 IP \u8303\u56f4 -label.private.ips=\u4e13\u7528 IP \u5730\u5740 label.private.ip=\u4e13\u7528 IP \u5730\u5740 -label.privatekey=PKCS\#8 \u79c1\u94a5 +label.private.ips=\u4e13\u7528 IP \u5730\u5740 label.private.network=\u4e13\u7528\u7f51\u7edc label.private.port=\u4e13\u7528\u7aef\u53e3 label.private.zone=\u4e13\u7528\u533a\u57df +label.privatekey=PKCS\#8 \u79c1\u94a5 label.project.dashboard=\u9879\u76ee\u63a7\u5236\u677f label.project.id=\u9879\u76ee ID label.project.invite=\u9080\u8bf7\u52a0\u5165\u9879\u76ee label.project.name=\u9879\u76ee\u540d\u79f0 -label.projects=\u9879\u76ee -label.project=\u9879\u76ee label.project.view=\u9879\u76ee\u89c6\u56fe +label.project=\u9879\u76ee +label.projects=\u9879\u76ee label.protocol=\u534f\u8bae label.providers=\u63d0\u4f9b\u7a0b\u5e8f label.public.interface=\u516c\u7528\u63a5\u53e3 -label.public.ips=\u516c\u7528 IP \u5730\u5740 label.public.ip=\u516c\u7528 IP \u5730\u5740 +label.public.ips=\u516c\u7528 IP \u5730\u5740 label.public.network=\u516c\u7528\u7f51\u7edc label.public.port=\u516c\u7528\u7aef\u53e3 label.public.traffic=\u516c\u5171\u6d41\u91cf -label.public=\u516c\u7528 label.public.zone=\u516c\u7528\u533a\u57df +label.public=\u516c\u7528 label.purpose=\u76ee\u7684 label.Pxe.server.type=Pxe \u670d\u52a1\u5668\u7c7b\u578b label.quickview=\u5feb\u901f\u67e5\u770b -label.reboot=\u00e9\u0087\u008d\u00e6\u0096\u00b0\u00e5\u0090\u00af\u00e5\u008a\u00a8 +label.reboot=\u91cd\u65b0\u542f\u52a8 label.recent.errors=\u6700\u8fd1\u51fa\u73b0\u7684\u9519\u8bef label.redundant.router.capability=\u5197\u4f59\u8def\u7531\u5668\u529f\u80fd label.redundant.router=\u5197\u4f59\u8def\u7531\u5668 @@ -895,24 +914,24 @@ label.remove.static.route=\u5220\u9664\u9759\u6001\u8def\u7531 label.remove.tier=\u5220\u9664\u5c42 label.remove.vm.from.lb=\u4ece\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219\u4e2d\u5220\u9664 VM label.remove.vpc=\u5220\u9664 VPC -label.removing=\u6b63\u5728\u5220\u9664 label.removing.user=\u6b63\u5728\u5220\u9664\u7528\u6237 -label.required=\u5fc5\u987b\u7684 +label.removing=\u6b63\u5728\u5220\u9664 +label.required=\u5fc5\u586b\u9879 label.reserved.system.gateway=\u9884\u7559\u7684\u7cfb\u7edf\u7f51\u5173 label.reserved.system.ip=\u9884\u7559\u7684\u7cfb\u7edf IP label.reserved.system.netmask=\u9884\u7559\u7684\u7cfb\u7edf\u7f51\u7edc\u63a9\u7801 label.reset.VPN.connection=\u91cd\u7f6e VPN \u8fde\u63a5 -label.resize.new.offering.id=New Offering -label.resize.new.size=New Size(GB) -label.resize.shrink.ok=Shrink OK +label.resize.new.offering.id=\u65b0\u5efa\u65b9\u6848 +label.resize.new.size=\u65b0\u5efa\u5927\u5c0f(GB) +label.resize.shrink.ok=\u662f\u5426\u786e\u5b9e\u8981\u7f29\u5c0f\u5377\u5927\u5c0f label.resource.limits=\u8d44\u6e90\u9650\u5236 label.resource.state=\u8d44\u6e90\u72b6\u6001 -label.resources=\u8d44\u6e90 label.resource=\u8d44\u6e90 +label.resources=\u8d44\u6e90 label.restart.network=\u91cd\u65b0\u542f\u52a8\u7f51\u7edc label.restart.required=\u9700\u8981\u91cd\u65b0\u542f\u52a8 label.restart.vpc=\u91cd\u65b0\u542f\u52a8 VPC -label.restore=\u6062\u590d +label.restore=\u8fd8\u539f label.review=\u6838\u5bf9 label.revoke.project.invite=\u64a4\u9500\u9080\u8bf7 label.role=\u89d2\u8272 @@ -921,14 +940,14 @@ label.root.disk.offering=\u6839\u78c1\u76d8\u65b9\u6848 label.round.robin=\u8f6e\u8be2\u7b97\u6cd5 label.rules=\u89c4\u5219 label.running.vms=\u6b63\u5728\u8fd0\u884c\u7684 VM -label.s3.access_key=\u8bbf\u95ee\u952e -label.s3.bucket=Bucket +label.s3.access_key=\u8bbf\u95ee\u5bc6\u94a5 +label.s3.bucket=\u5b58\u50a8\u6876 label.s3.connection_timeout=\u8fde\u63a5\u8d85\u65f6 label.s3.endpoint=\u7aef\u70b9 -label.s3.max_error_retry=\u6700\u5927\u9519\u8bef\u91cd\u8bd5 -label.s3.secret_key=\u00e5\u00af\u0086\u00e9\u0092\u00a5 -label.s3.socket_timeout=Socket\u8d85\u65f6 -label.s3.use_https=\u4f7f\u7528HTTPS +label.s3.max_error_retry=\u6700\u5927\u9519\u8bef\u91cd\u8bd5\u6b21\u6570 +label.s3.secret_key=\u5bc6\u94a5 +label.s3.socket_timeout=\u5957\u63a5\u5b57\u8d85\u65f6 +label.s3.use_https=\u4f7f\u7528 HTTPS label.saturday=\u661f\u671f\u516d label.save.and.continue=\u4fdd\u5b58\u5e76\u7ee7\u7eed label.save=\u4fdd\u5b58 @@ -936,15 +955,16 @@ label.saving.processing=\u6b63\u5728\u4fdd\u5b58... label.scope=\u8303\u56f4 label.search=\u641c\u7d22 label.secondary.storage.count=\u8f85\u52a9\u5b58\u50a8\u6c60 -label.secondary.storage.limits=\u4e8c\u7ea7\u5b58\u50a8\u9650\u5236(G\u5b57\u8282) -label.secondary.storage=\u4e8c\u7ea7\u5b58\u50a8 +label.secondary.storage.limits=\u8f85\u52a9\u5b58\u50a8\u9650\u5236(GiB) label.secondary.storage.vm=\u8f85\u52a9\u5b58\u50a8 VM +label.secondary.storage=\u8f85\u52a9\u5b58\u50a8 label.secondary.used=\u5df2\u4f7f\u7528\u7684\u8f85\u52a9\u5b58\u50a8 label.secret.key=\u5bc6\u94a5 label.security.group.name=\u5b89\u5168\u7ec4\u540d\u79f0 -label.security.groups.enabled=\u5df2\u542f\u7528\u5b89\u5168\u7ec4 -label.security.groups=\u5b89\u5168\u5206\u7ec4 label.security.group=\u5b89\u5168\u7ec4 +label.security.groups.enabled=\u5df2\u542f\u7528\u5b89\u5168\u7ec4 +label.security.groups=\u5b89\u5168\u7ec4 +label.select-view=\u9009\u62e9\u89c6\u56fe label.select.a.template=\u9009\u62e9\u4e00\u4e2a\u6a21\u677f label.select.a.zone=\u9009\u62e9\u4e00\u4e2a\u533a\u57df label.select.instance.to.attach.volume.to=\u9009\u62e9\u8981\u5c06\u5377\u9644\u52a0\u5230\u7684\u5b9e\u4f8b @@ -953,31 +973,30 @@ label.select.iso.or.template=\u9009\u62e9 ISO \u6216\u6a21\u677f label.select.offering=\u9009\u62e9\u65b9\u6848 label.select.project=\u9009\u62e9\u9879\u76ee label.select.tier=\u9009\u62e9\u5c42 -label.select=\u9009\u62e9 -label.select-view=\u9009\u62e9\u89c6\u56fe label.select.vm.for.static.nat=\u4e3a\u9759\u6001 NAT \u9009\u62e9 VM +label.select=\u9009\u62e9 label.sent=\u5df2\u53d1\u9001 label.server=\u670d\u52a1\u5668 label.service.capabilities=\u670d\u52a1\u529f\u80fd label.service.offering=\u670d\u52a1\u65b9\u6848 label.session.expired=\u4f1a\u8bdd\u5df2\u8fc7\u671f -label.setup.network=\u8bbe\u7f6e\u7f51\u7edc -label.setup=\u8bbe\u7f6e label.set.up.zone.type=\u8bbe\u7f6e\u533a\u57df\u7c7b\u578b +label.setup.network=\u8bbe\u7f6e\u7f51\u7edc label.setup.zone=\u8bbe\u7f6e\u533a\u57df -label.SharedMountPoint=SharedMountPoint +label.setup=\u8bbe\u7f6e label.shared=\u5df2\u5171\u4eab +label.SharedMountPoint=SharedMountPoint label.show.ingress.rule=\u663e\u793a\u5165\u53e3\u89c4\u5219 label.shutdown.provider=\u5173\u95ed\u63d0\u4f9b\u7a0b\u5e8f -label.site.to.site.VPN=\u7ad9\u70b9\u5230\u7ad9\u70b9 VPN +label.site.to.site.VPN=\u70b9\u5bf9\u70b9 VPN label.size=\u5927\u5c0f label.skip.guide=\u6211\u4ee5\u524d\u4f7f\u7528\u8fc7 CloudStack\uff0c\u8df3\u8fc7\u6b64\u6307\u5357 label.snapshot.limits=\u5feb\u7167\u9650\u5236 label.snapshot.name=\u5feb\u7167\u540d\u79f0 -label.snapshot.schedule=\u8bbe\u7f6e\u91cd\u73b0\u5feb\u7167 label.snapshot.s=\u5feb\u7167 -label.snapshots=\u5feb\u7167 +label.snapshot.schedule=\u8bbe\u7f6e\u91cd\u73b0\u5feb\u7167 label.snapshot=\u5feb\u7167 +label.snapshots=\u5feb\u7167 label.source.nat=\u6e90 NAT label.source=\u6e90\u7b97\u6cd5 label.specify.IP.ranges=\u6307\u5b9a IP \u8303\u56f4 @@ -991,8 +1010,8 @@ label.start.vlan=\u8d77\u59cb VLAN label.state=\u72b6\u6001 label.static.nat.enabled=\u5df2\u542f\u7528\u9759\u6001 NAT label.static.nat.to=\u9759\u6001 NAT \u76ee\u6807 -label.static.nat=\u9759\u6001 NAT label.static.nat.vm.details=\u9759\u6001 NAT VM \u8be6\u60c5 +label.static.nat=\u9759\u6001 NAT label.statistics=\u7edf\u8ba1\u6570\u636e label.status=\u72b6\u6001 label.step.1.title=\u6b65\u9aa4 1\: \u9009\u62e9\u4e00\u4e2a\u6a21\u677f @@ -1018,15 +1037,15 @@ label.sticky.postonly=postonly label.sticky.prefix=prefix label.sticky.request-learn=request-learn label.sticky.tablesize=\u8868\u5927\u5c0f +label.stop=\u505c\u6b62 label.stopped.vms=\u5df2\u505c\u6b62\u7684 VM -label.stop=\u00e5\u0081\u009c\u00e6\u00ad\u00a2 label.storage.tags=\u5b58\u50a8\u6807\u7b7e label.storage.traffic=\u5b58\u50a8\u6d41\u91cf label.storage.type=\u5b58\u50a8\u7c7b\u578b label.storage=\u5b58\u50a8 label.subdomain.access=\u5b50\u57df\u8bbf\u95ee -label.submitted.by=[\u63d0\u4ea4\u8005\: ] label.submit=\u63d0\u4ea4 +label.submitted.by=[\u63d0\u4ea4\u8005\: ] label.succeeded=\u6210\u529f label.sunday=\u661f\u671f\u65e5 label.super.cidr.for.guest.networks=\u6765\u5bbe\u7f51\u7edc\u7684\u8d85\u7ea7 CIDR @@ -1036,9 +1055,9 @@ label.suspend.project=\u6682\u505c\u9879\u76ee label.system.capacity=\u7cfb\u7edf\u5bb9\u91cf label.system.offering=\u7cfb\u7edf\u65b9\u6848 label.system.service.offering=\u7cfb\u7edf\u670d\u52a1\u65b9\u6848 -label.system.vms=\u7cfb\u7edf VM label.system.vm.type=\u7cfb\u7edf VM \u7c7b\u578b label.system.vm=\u7cfb\u7edf VM +label.system.vms=\u7cfb\u7edf VM label.system.wide.capacity=\u5168\u7cfb\u7edf\u5bb9\u91cf label.tagged=\u5df2\u6807\u8bb0 label.tags=\u6807\u7b7e @@ -1053,14 +1072,14 @@ label.theme.lightblue=\u81ea\u5b9a\u4e49 - \u6de1\u84dd\u8272 label.thursday=\u661f\u671f\u56db label.tier.details=\u5c42\u8be6\u7ec6\u4fe1\u606f label.tier=\u5c42 +label.time.zone=\u65f6\u533a +label.time=\u65f6\u95f4 label.timeout.in.second = \u8d85\u65f6(\u79d2) label.timeout=\u8d85\u65f6 -label.time=\u65f6\u95f4 -label.time.zone=\u65f6\u533a label.timezone=\u65f6\u533a label.token=\u4ee4\u724c -label.total.cpu=CPU \u603b\u91cf label.total.CPU=CPU \u603b\u91cf +label.total.cpu=CPU \u603b\u91cf label.total.hosts=\u603b\u4e3b\u673a\u6570 label.total.memory=\u5185\u5b58\u603b\u91cf label.total.of.ip=\u603b IP \u5730\u5740\u6570 @@ -1068,8 +1087,8 @@ label.total.of.vm=\u603b VM \u6570 label.total.storage=\u5b58\u50a8\u603b\u91cf label.total.vms=\u603b VM \u6570 label.traffic.label=\u6d41\u91cf\u6807\u7b7e -label.traffic.types=\u6d41\u91cf\u7c7b\u578b label.traffic.type=\u6d41\u91cf\u7c7b\u578b +label.traffic.types=\u6d41\u91cf\u7c7b\u578b label.tuesday=\u661f\u671f\u4e8c label.type.id=\u7c7b\u578b ID label.type=\u7c7b\u578b @@ -1077,18 +1096,18 @@ label.unavailable=\u4e0d\u53ef\u7528 label.unlimited=\u65e0\u9650\u5236 label.untagged=\u5df2\u53d6\u6d88\u6807\u8bb0 label.update.project.resources=\u66f4\u65b0\u9879\u76ee\u8d44\u6e90 -label.update.ssl.cert= \u66f4\u65b0 SSL \u8bc1\u4e66 -label.update.ssl= \u66f4\u65b0 SSL \u8bc1\u4e66 +label.update.ssl.cert= SSL \u8bc1\u4e66 +label.update.ssl= SSL \u8bc1\u4e66 label.updating=\u6b63\u5728\u66f4\u65b0 -label.upload=\u4e0a\u8f7d label.upload.volume=\u4e0a\u8f7d\u5377 +label.upload=\u4e0a\u8f7d label.url=URL label.usage.interface=\u4f7f\u7528\u754c\u9762 +label.use.vm.ip=\u4f7f\u7528 VM IP\: label.used=\u5df2\u4f7f\u7528 -label.username=\u7528\u6237\u540d -label.users=\u666e\u901a\u7528\u6237 label.user=\u7528\u6237 -label.use.vm.ip=\u4f7f\u7528\u865a\u673aIP\: +label.username=\u7528\u6237\u540d +label.users=\u7528\u6237 label.value=\u503c label.vcdcname=vCenter DC \u540d\u79f0 label.vcenter.cluster=vCenter \u7fa4\u96c6 @@ -1101,47 +1120,47 @@ label.vcipaddress=vCenter IP \u5730\u5740 label.version=\u7248\u672c label.view.all=\u67e5\u770b\u5168\u90e8 label.view.console=\u67e5\u770b\u63a7\u5236\u53f0 -label.viewing=\u6b63\u5728\u67e5\u770b label.view.more=\u67e5\u770b\u66f4\u591a label.view=\u67e5\u770b -label.virtual.appliances=\u865a\u62df\u8bbe\u5907 +label.viewing=\u6b63\u5728\u67e5\u770b label.virtual.appliance=\u865a\u62df\u8bbe\u5907 +label.virtual.appliances=\u865a\u62df\u8bbe\u5907 label.virtual.machines=\u865a\u62df\u673a label.virtual.network=\u865a\u62df\u7f51\u7edc -label.virtual.routers=\u865a\u62df\u8def\u7531\u5668 label.virtual.router=\u865a\u62df\u8def\u7531\u5668 +label.virtual.routers=\u865a\u62df\u8def\u7531\u5668 label.vlan.id=VLAN ID label.vlan.range=VLAN \u8303\u56f4 label.vlan=VLAN label.vm.add=\u6dfb\u52a0\u5b9e\u4f8b label.vm.destroy=\u9500\u6bc1 label.vm.display.name=VM \u663e\u793a\u540d\u79f0 -label.VMFS.datastore=VMFS \u6570\u636e\u5b58\u50a8 -label.vmfs=VMFS label.vm.name=VM \u540d\u79f0 label.vm.reboot=\u91cd\u65b0\u542f\u52a8 -label.VMs.in.tier=\u5c42\u4e2d\u7684 VM -label.vmsnapshot.current=\u5f53\u524d\u6700\u65b0 -label.vmsnapshot.memory=\u5236\u4f5c\u5185\u5b58\u5feb\u7167 -label.vmsnapshot.parentname=\u6839 -label.vmsnapshot.type=\u00e7\u00b1\u00bb\u00e5\u009e\u008b -label.vmsnapshot=\u865a\u673a\u5feb\u7167 label.vm.start=\u542f\u52a8 label.vm.state=VM \u72b6\u6001 label.vm.stop=\u505c\u6b62 +label.VMFS.datastore=VMFS \u6570\u636e\u5b58\u50a8 +label.vmfs=VMFS +label.VMs.in.tier=\u5c42\u4e2d\u7684 VM label.vms=VM +label.vmsnapshot.current=\u6700\u65b0\u7248\u672c +label.vmsnapshot.memory=\u5feb\u7167\u5185\u5b58 +label.vmsnapshot.parentname=\u7236\u540d\u79f0 +label.vmsnapshot.type=\u7c7b\u578b +label.vmsnapshot=VM \u5feb\u7167 label.vmware.traffic.label=VMware \u6d41\u91cf\u6807\u7b7e label.volgroup=\u5377\u7ec4 label.volume.limits=\u5377\u9650\u5236 label.volume.name=\u5377\u540d\u79f0 -label.volumes=\u5377 label.volume=\u5377 +label.volumes=\u5377 label.vpc.id=VPC ID label.VPC.router.details=VPC \u8def\u7531\u5668\u8be6\u7ec6\u4fe1\u606f label.vpc=VPC label.VPN.connection=VPN \u8fde\u63a5 -label.vpn.customer.gateway=VPN \u5ba2\u6237\u7f51\u5173 label.VPN.customer.gateway=VPN \u5ba2\u6237\u7f51\u5173 +label.vpn.customer.gateway=VPN \u5ba2\u6237\u7f51\u5173 label.VPN.gateway=VPN \u7f51\u5173 label.vpn=VPN label.vsmctrlvlanid=\u63a7\u5236 VLAN ID @@ -1164,17 +1183,17 @@ label.zone.step.1.title=\u6b65\u9aa4 1\: \u9009\u62e9\u4e00\u4e2a\u7f51\ label.zone.step.2.title=\u6b65\u9aa4 2\: \u6dfb\u52a0\u4e00\u4e2a\u533a\u57df label.zone.step.3.title=\u6b65\u9aa4 3\: \u6dfb\u52a0\u4e00\u4e2a\u63d0\u4f9b\u70b9 label.zone.step.4.title=\u6b65\u9aa4 4\: \u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4 -label.zones=\u533a\u57df label.zone.type=\u533a\u57df\u7c7b\u578b -label.zone=\u533a\u57df label.zone.wide=\u6574\u4e2a\u533a\u57df -label.zoneWizard.trafficType.guest=\u6765\u5bbe\u7f51\u7edc\: \u5ba2\u6237\u865a\u62df\u673a\u4e4b\u95f4\u7684\u7f51\u7edc\u6d41\u91cf -label.zoneWizard.trafficType.management=\u7ba1\u7406\u7f51\: CloudStack\u5185\u90e8\u8d44\u6e90\u4e4b\u95f4\u7684\u7f51\u7edc\u6d41\u91cf, \u5305\u62ec\u4e0e\u7ba1\u7406\u670d\u52a1\u5668\u4ea4\u4e92\u7684\u4efb\u4f55\u7ec4\u4ef6, \u6bd4\u5982\u4e3b\u673a\u548cCloudStack\u7cfb\u7edf\u865a\u62df\u673a -label.zoneWizard.trafficType.public=\u516c\u5171\u7f51\u7edc\: \u4e91\u73af\u5883\u4e2d\u865a\u62df\u673a\u4e0e\u56e0\u7279\u7f51\u4e4b\u95f4\u7684\u7f51\u7edc\u6d41\u91cf. -label.zoneWizard.trafficType.storage=\u5b58\u50a8\u7f51\: \u4e3b\u5b58\u50a8\u4e0e\u4e8c\u7ea7\u5b58\u50a8\u670d\u52a1\u5668\u4e4b\u95f4\u7684\u6d41\u91cf, \u6bd4\u5982\u865a\u673a\u6a21\u677f\u548c\u5feb\u7167 +label.zone=\u533a\u57df +label.zones=\u533a\u57df +label.zoneWizard.trafficType.guest=\u6765\u5bbe\: \u6700\u7ec8\u7528\u6237\u865a\u62df\u673a\u4e4b\u95f4\u7684\u6d41\u91cf +label.zoneWizard.trafficType.management=\u7ba1\u7406\: CloudStack \u7684\u5185\u90e8\u8d44\u6e90(\u5305\u62ec\u4e0e\u7ba1\u7406\u670d\u52a1\u5668\u901a\u4fe1\u7684\u4efb\u4f55\u7ec4\u4ef6\uff0c\u4f8b\u5982\u4e3b\u673a\u548c CloudStack \u7cfb\u7edf VM)\u4e4b\u95f4\u7684\u6d41\u91cf +label.zoneWizard.trafficType.public=\u516c\u7528\: \u4e91\u4e2d Internet \u4e0e\u865a\u62df\u673a\u4e4b\u95f4\u7684\u6d41\u91cf\u3002 +label.zoneWizard.trafficType.storage=\u5b58\u50a8\: \u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u4e0e\u8f85\u52a9\u5b58\u50a8\u670d\u52a1\u5668(\u4f8b\u5982 VM \u6a21\u677f\u4e0e\u5feb\u7167)\u4e4b\u95f4\u7684\u6d41\u91cf managed.state=\u6258\u7ba1\u72b6\u6001 +message.acquire.new.ip.vpc=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64 VPC \u83b7\u53d6\u4e00\u4e2a\u65b0 IP\u3002 message.acquire.new.ip=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64\u7f51\u7edc\u83b7\u53d6\u4e00\u4e2a\u65b0 IP\u3002 -message.acquire.new.ip.vpc=\u8bf7\u786e\u8ba4\u4f60\u60f3\u8981\u4e3a\u6b64VPC\u83b7\u5f97\u65b0\u7684IP message.acquire.public.ip=\u8bf7\u9009\u62e9\u4e00\u4e2a\u8981\u4ece\u4e2d\u83b7\u53d6\u65b0 IP \u7684\u533a\u57df\u3002 message.action.cancel.maintenance.mode=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u53d6\u6d88\u6b64\u7ef4\u62a4\u3002 message.action.cancel.maintenance=\u5df2\u6210\u529f\u53d6\u6d88\u7ef4\u62a4\u60a8\u7684\u4e3b\u673a\u3002\u6b64\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u957f\u8fbe\u51e0\u5206\u949f\u65f6\u95f4\u3002 @@ -1206,7 +1225,7 @@ message.action.destroy.instance=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u9500 message.action.destroy.systemvm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u9500\u6bc1\u6b64\u7cfb\u7edf VM\u3002 message.action.disable.cluster=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u7fa4\u96c6\u3002 message.action.disable.nexusVswitch=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64 Nexus 1000v -message.action.disable.physical.network=\u8bf7\u4f60\u786e\u8ba4\u662f\u662f\u5426\u9700\u8981\u7981\u7528\u8fd9\u4e2a\u7269\u7406\u7f51\u7edc\u3002 +message.action.disable.physical.network=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u7269\u7406\u7f51\u7edc\u3002 message.action.disable.pod=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u63d0\u4f9b\u70b9\u3002 message.action.disable.static.NAT=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u9759\u6001 NAT\u3002 message.action.disable.zone=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u533a\u57df\u3002 @@ -1215,7 +1234,7 @@ message.action.download.template=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e0 message.action.enable.cluster=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u7fa4\u96c6\u3002 message.action.enable.maintenance=\u5df2\u6210\u529f\u51c6\u5907\u597d\u7ef4\u62a4\u60a8\u7684\u4e3b\u673a\u3002\u6b64\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u957f\u8fbe\u51e0\u5206\u949f\u6216\u66f4\u957f\u65f6\u95f4\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u5f53\u524d\u6b64\u4e3b\u673a\u4e0a\u7684 VM \u6570\u91cf\u3002 message.action.enable.nexusVswitch=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64 Nexus 1000v -message.action.enable.physical.network=\u8bf7\u4f60\u786e\u8ba4\u662f\u662f\u5426\u9700\u8981\u542f\u7528\u8fd9\u4e2a\u7269\u7406\u7f51\u7edc\u3002 +message.action.enable.physical.network=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u7269\u7406\u7f51\u7edc\u3002 message.action.enable.pod=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u63d0\u4f9b\u70b9\u3002 message.action.enable.zone=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u533a\u57df\u3002 message.action.force.reconnect=\u5df2\u6210\u529f\u5f3a\u5236\u91cd\u65b0\u8fde\u63a5\u60a8\u7684\u4e3b\u673a\u3002\u6b64\u8fc7\u7a0b\u53ef\u80fd\u9700\u8981\u957f\u8fbe\u51e0\u5206\u949f\u65f6\u95f4\u3002 @@ -1239,42 +1258,42 @@ message.action.stop.router=\u6b64\u865a\u62df\u8def\u7531\u5668\u63d0\u4f9b\u768 message.action.stop.systemvm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u505c\u6b62\u6b64\u7cfb\u7edf VM\u3002 message.action.take.snapshot=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u521b\u5efa\u6b64\u5377\u7684\u5feb\u7167\u3002 message.action.unmanage.cluster=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u53d6\u6d88\u6258\u7ba1\u6b64\u7fa4\u96c6\u3002 -message.action.vmsnapshot.delete=\u8bf7\u786e\u8ba4\u4f60\u8981\u5220\u9664\u6b64\u865a\u673a\u7684\u5feb\u7167 -message.action.vmsnapshot.revert=\u6062\u590d\u865a\u673a\u5feb\u7167 +message.action.vmsnapshot.delete=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64 VM \u5feb\u7167\u3002 +message.action.vmsnapshot.revert=\u8fd8\u539f VM \u5feb\u7167 message.activate.project=\u662f\u5426\u786e\u5b9e\u8981\u6fc0\u6d3b\u6b64\u9879\u76ee? -message.add.cluster=\u5411\u533a\u57df \u3001\u63d0\u4f9b\u70b9 \u4e2d\u6dfb\u52a0\u4e00\u4e2a\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u6258\u7ba1\u7684\u7fa4\u96c6 message.add.cluster.zone=\u5411\u533a\u57df \u4e2d\u6dfb\u52a0\u4e00\u4e2a\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u6258\u7ba1\u7684\u7fa4\u96c6 +message.add.cluster=\u5411\u533a\u57df \u3001\u63d0\u4f9b\u70b9 \u4e2d\u6dfb\u52a0\u4e00\u4e2a\u865a\u62df\u673a\u7ba1\u7406\u7a0b\u5e8f\u6258\u7ba1\u7684\u7fa4\u96c6 message.add.disk.offering=\u8bf7\u6307\u5b9a\u4ee5\u4e0b\u53c2\u6570\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u78c1\u76d8\u65b9\u6848 message.add.domain=\u8bf7\u6307\u5b9a\u8981\u5728\u6b64\u57df\u4e0b\u521b\u5efa\u7684\u5b50\u57df message.add.firewall=\u5411\u533a\u57df\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u9632\u706b\u5899 message.add.guest.network=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u6dfb\u52a0\u4e00\u4e2a\u6765\u5bbe\u7f51\u7edc message.add.host=\u8bf7\u6307\u5b9a\u4ee5\u4e0b\u53c2\u6570\u4ee5\u6dfb\u52a0\u4e00\u53f0\u65b0\u4e3b\u673a -message.adding.host=\u6b63\u5728\u6dfb\u52a0\u4e3b\u673a -message.adding.Netscaler.device=\u6b63\u5728\u6dfb\u52a0 Netscaler \u8bbe\u5907 -message.adding.Netscaler.provider=\u6b63\u5728\u6dfb\u52a0 Netscaler \u63d0\u4f9b\u7a0b\u5e8f message.add.ip.range.direct.network=\u5411\u533a\u57df \u4e2d\u7684\u76f4\u63a5\u7f51\u7edc \u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4 message.add.ip.range.to.pod=

\u5411\u63d0\u4f9b\u70b9\u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4\:

message.add.ip.range=\u5411\u533a\u57df\u4e2d\u7684\u516c\u7528\u7f51\u7edc\u6dfb\u52a0\u4e00\u4e2a IP \u8303\u56f4 -message.additional.networks.desc=\u8bf7\u9009\u62e9\u865a\u62df\u673a\u8981\u8fde\u63a5\u5230\u7684\u5176\u4ed6\u7f51\u7edc\u3002 -message.add.load.balancer=\u5411\u533a\u57df\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u8d1f\u8f7d\u5e73\u8861\u5668 message.add.load.balancer.under.ip=\u5df2\u5728\u4ee5\u4e0b IP \u4e0b\u6dfb\u52a0\u8d1f\u8f7d\u5e73\u8861\u5668\u89c4\u5219\: -message.add.network=\u4e3a\u533a\u57df\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7f51\u7edc\: +message.add.load.balancer=\u5411\u533a\u57df\u4e2d\u6dfb\u52a0\u4e00\u4e2a\u8d1f\u8f7d\u5e73\u8861\u5668 +message.add.network=\u4e3a\u533a\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u7f51\u7edc message.add.new.gateway.to.vpc=\u8bf7\u6307\u5b9a\u5c06\u65b0\u7f51\u5173\u6dfb\u52a0\u5230\u6b64 VPC \u6240\u9700\u7684\u4fe1\u606f\u3002 message.add.pod.during.zone.creation=\u6bcf\u4e2a\u533a\u57df\u4e2d\u5fc5\u987b\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\uff0c\u73b0\u5728\u6211\u4eec\u5c06\u6dfb\u52a0\u7b2c\u4e00\u4e2a\u63d0\u4f9b\u70b9\u3002\u63d0\u4f9b\u70b9\u4e2d\u5305\u542b\u4e3b\u673a\u548c\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\uff0c\u60a8\u5c06\u5728\u968f\u540e\u7684\u67d0\u4e2a\u6b65\u9aa4\u4e2d\u6dfb\u52a0\u8fd9\u4e9b\u4e3b\u673a\u548c\u670d\u52a1\u5668\u3002\u9996\u5148\uff0c\u8bf7\u4e3a CloudStack \u7684\u5185\u90e8\u7ba1\u7406\u6d41\u91cf\u914d\u7f6e\u4e00\u4e2a\u9884\u7559 IP \u5730\u5740\u8303\u56f4\u3002\u9884\u7559\u7684 IP \u8303\u56f4\u5bf9\u4e91\u4e2d\u7684\u6bcf\u4e2a\u533a\u57df\u6765\u8bf4\u5fc5\u987b\u552f\u4e00\u3002 message.add.pod=\u4e3a\u533a\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u63d0\u4f9b\u70b9 -message.add.primary.storage=\u4e3a\u533a\u57df \u3001\u63d0\u4f9b\u70b9 \u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u4e3b\u5b58\u50a8 +message.add.primary.storage=\u4e3a\u533a\u57df \u3001\u63d0\u4f9b\u70b9 \u6dfb\u52a0\u4e00\u4e2a\u65b0\u4e3b\u5b58\u50a8 message.add.primary=\u8bf7\u6307\u5b9a\u4ee5\u4e0b\u53c2\u6570\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u4e3b\u5b58\u50a8 -message.add.region=\u8bf7\u6307\u5b9a\u9700\u8981\u7684\u4fe1\u606f\u4ee5\u6dfb\u52a0\u65b0\u7684\u533a\u57df +message.add.region=\u8bf7\u6307\u5b9a\u6dfb\u52a0\u65b0\u533a\u57df\u6240\u9700\u7684\u4fe1\u606f\u3002 message.add.secondary.storage=\u4e3a\u533a\u57df \u6dfb\u52a0\u4e00\u4e2a\u65b0\u5b58\u50a8 message.add.service.offering=\u8bf7\u586b\u5199\u4ee5\u4e0b\u6570\u636e\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u8ba1\u7b97\u65b9\u6848\u3002 message.add.system.service.offering=\u8bf7\u586b\u5199\u4ee5\u4e0b\u6570\u636e\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u7cfb\u7edf\u670d\u52a1\u65b9\u6848\u3002 message.add.template=\u8bf7\u8f93\u5165\u4ee5\u4e0b\u6570\u636e\u4ee5\u521b\u5efa\u65b0\u6a21\u677f message.add.volume=\u8bf7\u586b\u5199\u4ee5\u4e0b\u6570\u636e\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u5377\u3002 message.add.VPN.gateway=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u6dfb\u52a0 VPN \u7f51\u5173 +message.adding.host=\u6b63\u5728\u6dfb\u52a0\u4e3b\u673a +message.adding.Netscaler.device=\u6b63\u5728\u6dfb\u52a0 Netscaler \u8bbe\u5907 +message.adding.Netscaler.provider=\u6b63\u5728\u6dfb\u52a0 Netscaler \u63d0\u4f9b\u7a0b\u5e8f +message.additional.networks.desc=\u8bf7\u9009\u62e9\u865a\u62df\u673a\u8981\u8fde\u63a5\u5230\u7684\u5176\u4ed6\u7f51\u7edc\u3002 message.advanced.mode.desc=\u5982\u679c\u60a8\u5e0c\u671b\u542f\u7528 VLAN \u652f\u6301\uff0c\u8bf7\u9009\u62e9\u6b64\u7f51\u7edc\u6a21\u5f0f\u3002\u6b64\u7f51\u7edc\u6a21\u5f0f\u5728\u5141\u8bb8\u7ba1\u7406\u5458\u63d0\u4f9b\u9632\u706b\u5899\u3001VPN \u6216\u8d1f\u8f7d\u5e73\u8861\u5668\u652f\u6301\u7b49\u81ea\u5b9a\u4e49\u7f51\u7edc\u65b9\u6848\u4ee5\u53ca\u542f\u7528\u76f4\u63a5\u7f51\u7edc\u8fde\u63a5\u4e0e\u865a\u62df\u7f51\u7edc\u8fde\u63a5\u7b49\u65b9\u9762\u63d0\u4f9b\u4e86\u6700\u5927\u7684\u7075\u6d3b\u6027\u3002 message.advanced.security.group=\u5982\u679c\u8981\u4f7f\u7528\u5b89\u5168\u7ec4\u63d0\u4f9b\u6765\u5bbe VM \u9694\u79bb\uff0c\u8bf7\u9009\u62e9\u6b64\u6a21\u5f0f\u3002 message.advanced.virtual=\u5982\u679c\u8981\u4f7f\u7528\u6574\u4e2a\u533a\u57df\u7684 VLAN \u63d0\u4f9b\u6765\u5bbe VM \u9694\u79bb\uff0c\u8bf7\u9009\u62e9\u6b64\u6a21\u5f0f\u3002 -message.after.enable.s3=\u5df2\u914d\u7f6e\u652f\u6301S3\u7684\u4e8c\u7ea7\u5b58\u50a8. \u6ce8\u610f\: \u5f53\u4f60\u79bb\u5f00\u6b64\u9875\u9762, \u4f60\u5c06\u65e0\u6cd5\u518d\u6b21\u914d\u7f6eS3. +message.after.enable.s3=\u5df2\u914d\u7f6e S3 \u652f\u6301\u7684\u8f85\u52a9\u5b58\u50a8\u3002\u6ce8\u610f\: \u9000\u51fa\u6b64\u9875\u9762\u540e\uff0c\u60a8\u5c06\u65e0\u6cd5\u518d\u6b21\u91cd\u65b0\u914d\u7f6e S3\u3002 message.after.enable.swift=\u5df2\u914d\u7f6e SWIFT\u3002\u6ce8\u610f\: \u9000\u51fa\u6b64\u9875\u9762\u540e\uff0c\u60a8\u5c06\u65e0\u6cd5\u518d\u6b21\u91cd\u65b0\u914d\u7f6e SWIFT\u3002 message.alert.state.detected=\u68c0\u6d4b\u5230\u8b66\u62a5\u72b6\u6001 message.allow.vpn.access=\u8bf7\u8f93\u5165\u8981\u5141\u8bb8\u8fdb\u884c VPN \u8bbf\u95ee\u7684\u7528\u6237\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002 @@ -1301,9 +1320,9 @@ message.confirm.remove.IP.range=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220 message.confirm.shutdown.provider=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5173\u95ed\u6b64\u63d0\u4f9b\u7a0b\u5e8f message.copy.iso.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5c06 ISO \u590d\u5236\u5230 message.copy.template=\u5c06\u6a21\u677f XXX \u4ece\u533a\u57df \u590d\u5236\u5230 -message.create.template=\u662f\u5426\u786e\u5b9e\u8981\u521b\u5efa\u6a21\u677f? message.create.template.vm=\u57fa\u4e8e\u6a21\u677f \u521b\u5efa VM -message.create.template.volume=\u8bf7\u5148\u6307\u5b9a\u4ee5\u4e0b\u4fe1\u606f\uff0c\u7136\u540e\u518d\u521b\u5efa\u78c1\u76d8\u5377\u7684\u6a21\u677f\: \u3002\u521b\u5efa\u6a21\u677f\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u5230\u66f4\u957f\u7684\u65f6\u95f4\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u78c1\u76d8\u5377\u7684\u5927\u5c0f\u3002 +message.create.template.volume=\u8bf7\u5148\u6307\u5b9a\u4ee5\u4e0b\u4fe1\u606f\uff0c\u7136\u540e\u518d\u521b\u5efa\u78c1\u76d8\u5377 \u7684\u6a21\u677f\u3002\u521b\u5efa\u6a21\u677f\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u5230\u66f4\u957f\u7684\u65f6\u95f4\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u78c1\u76d8\u5377\u7684\u5927\u5c0f\u3002 +message.create.template=\u662f\u5426\u786e\u5b9e\u8981\u521b\u5efa\u6a21\u677f? message.creating.cluster=\u6b63\u5728\u521b\u5efa\u7fa4\u96c6 message.creating.guest.network=\u6b63\u5728\u521b\u5efa\u6765\u5bbe\u7f51\u7edc message.creating.physical.networks=\u6b63\u5728\u521b\u5efa\u7269\u7406\u7f51\u7edc @@ -1313,6 +1332,7 @@ message.creating.secondary.storage=\u6b63\u5728\u521b\u5efa\u8f85\u52a9\u5b58\u5 message.creating.zone=\u6b63\u5728\u521b\u5efa\u533a\u57df message.decline.invitation=\u662f\u5426\u786e\u5b9e\u8981\u62d2\u7edd\u6b64\u9879\u76ee\u9080\u8bf7? message.delete.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5e10\u6237\u3002 +message.delete.affinity.group=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u5173\u8054\u6027\u7ec4\u3002 message.delete.gateway=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u7f51\u5173 message.delete.project=\u662f\u5426\u786e\u5b9e\u8981\u5220\u9664\u6b64\u9879\u76ee? message.delete.user=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u6b64\u7528\u6237\u3002 @@ -1328,7 +1348,7 @@ message.desc.secondary.storage=\u6bcf\u4e2a\u533a\u57df\u4e2d\u5fc5\u987b\u81f3\ message.desc.zone=\u533a\u57df\u662f CloudStack \u4e2d\u6700\u5927\u7684\u7ec4\u7ec7\u5355\u4f4d\uff0c\u4e00\u4e2a\u533a\u57df\u901a\u5e38\u4e0e\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u76f8\u5bf9\u5e94\u3002\u533a\u57df\u53ef\u63d0\u4f9b\u7269\u7406\u9694\u79bb\u548c\u5197\u4f59\u3002\u4e00\u4e2a\u533a\u57df\u7531\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\u4ee5\u53ca\u7531\u533a\u57df\u4e2d\u7684\u6240\u6709\u63d0\u4f9b\u70b9\u5171\u4eab\u7684\u4e00\u4e2a\u8f85\u52a9\u5b58\u50a8\u670d\u52a1\u5668\u7ec4\u6210\uff0c\u5176\u4e2d\u6bcf\u4e2a\u63d0\u4f9b\u70b9\u4e2d\u5305\u542b\u591a\u4e2a\u4e3b\u673a\u548c\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u3002 message.detach.disk=\u662f\u5426\u786e\u5b9e\u8981\u53d6\u6d88\u9644\u52a0\u6b64\u78c1\u76d8? message.detach.iso.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4ece\u6b64\u865a\u62df\u673a\u4e2d\u53d6\u6d88\u9644\u52a0\u6b64 ISO\u3002 -message.disable.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u5e10\u6237\u3002\u901a\u8fc7\u7981\u7528\u6b64\u5e10\u6237\uff0c\u6b64\u5e10\u6237\u7684\u6240\u6709\u7528\u6237\u5c06\u4e0d\u518d\u6709\u6743\u8bbf\u95ee\u5404\u81ea\u7684\u4e91\u8d44\u6e90\u3002\u6240\u6709\u6b63\u5728\u8fd0\u884c\u7684\u865a\u62df\u673a\u5c06\u7acb\u5373\u5173\u95ed\u3002 +message.disable.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u5e10\u6237\u3002\u7981\u7528\u540e\uff0c\u6b64\u5e10\u6237\u7684\u6240\u6709\u7528\u6237\u5c06\u4e0d\u518d\u6709\u6743\u8bbf\u95ee\u5404\u81ea\u7684\u4e91\u8d44\u6e90\u3002\u6240\u6709\u6b63\u5728\u8fd0\u884c\u7684\u865a\u62df\u673a\u5c06\u7acb\u5373\u5173\u95ed\u3002 message.disable.snapshot.policy=\u60a8\u5df2\u6210\u529f\u7981\u7528\u5f53\u524d\u7684\u5feb\u7167\u7b56\u7565\u3002 message.disable.user=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528\u6b64\u7528\u6237\u3002 message.disable.vpn.access=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u7981\u7528 VPN \u8bbf\u95ee\u3002 @@ -1342,11 +1362,11 @@ message.edit.confirm=\u8bf7\u5148\u786e\u8ba4\u60a8\u6240\u505a\u7684\u66f4\u653 message.edit.limits=\u8bf7\u6307\u5b9a\u5bf9\u4ee5\u4e0b\u8d44\u6e90\u7684\u9650\u5236\u3002\u201c-1\u201d\u8868\u793a\u4e0d\u9650\u5236\u8981\u521b\u5efa\u7684\u8d44\u6e90\u6570\u3002 message.edit.traffic.type=\u8bf7\u6307\u5b9a\u60a8\u5e0c\u671b\u4e0e\u6b64\u6d41\u91cf\u7c7b\u578b\u5173\u8054\u7684\u6d41\u91cf\u6807\u7b7e\u3002 message.enable.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u5e10\u6237\u3002 -message.enabled.vpn.ip.sec=\u60a8\u7684 IPSec \u9884\u5171\u4eab\u5bc6\u94a5 -message.enabled.vpn=\u60a8\u7684 VPN \u8bbf\u95ee\u529f\u80fd\u5f53\u524d\u5df2\u542f\u7528\uff0c\u53ef\u4ee5\u901a\u8fc7 IP \u8fdb\u884c\u8bbf\u95ee message.enable.user=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u542f\u7528\u6b64\u7528\u6237\u3002 message.enable.vpn.access=\u5f53\u524d\u5df2\u5bf9\u6b64 IP \u5730\u5740\u7981\u7528\u4e86 VPN\u3002\u662f\u5426\u8981\u542f\u7528 VPN \u8bbf\u95ee? message.enable.vpn=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5bf9\u6b64 IP \u5730\u5740\u542f\u7528 VPN \u8bbf\u95ee\u3002 +message.enabled.vpn.ip.sec=\u60a8\u7684 IPSec \u9884\u5171\u4eab\u5bc6\u94a5 +message.enabled.vpn=\u60a8\u7684 VPN \u8bbf\u95ee\u529f\u80fd\u5f53\u524d\u5df2\u542f\u7528\uff0c\u53ef\u4ee5\u901a\u8fc7 IP \u8fdb\u884c\u8bbf\u95ee message.enabling.security.group.provider=\u6b63\u5728\u542f\u7528\u5b89\u5168\u7ec4\u63d0\u4f9b\u7a0b\u5e8f message.enabling.zone=\u6b63\u5728\u542f\u7528\u533a\u57df message.enter.token=\u8bf7\u8f93\u5165\u60a8\u5728\u9080\u8bf7\u7535\u5b50\u90ae\u4ef6\u4e2d\u6536\u5230\u7684\u4ee4\u724c\u3002 @@ -1359,9 +1379,9 @@ message.installWizard.copy.whatIsAHost=\u4e3b\u673a\u662f\u6307\u4e00\u53f0\u8ba message.installWizard.copy.whatIsAPod=\u4e00\u4e2a\u63d0\u4f9b\u70b9\u901a\u5e38\u4ee3\u8868\u4e00\u4e2a\u673a\u67b6\u3002\u540c\u4e00\u63d0\u4f9b\u70b9\u4e2d\u7684\u4e3b\u673a\u4f4d\u4e8e\u540c\u4e00\u5b50\u7f51\u4e2d\u3002

\u63d0\u4f9b\u70b9\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u7684\u7b2c\u4e8c\u5927\u7ec4\u7ec7\u5355\u4f4d\u3002\u63d0\u4f9b\u70b9\u5305\u542b\u5728\u533a\u57df\u4e2d\u3002\u6bcf\u4e2a\u533a\u57df\u4e2d\u53ef\u4ee5\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u63d0\u4f9b\u70b9\uff1b\u5728\u57fa\u672c\u5b89\u88c5\u4e2d\uff0c\u60a8\u7684\u533a\u57df\u4e2d\u5c06\u4ec5\u5305\u542b\u4e00\u4e2a\u63d0\u4f9b\u70b9\u3002 message.installWizard.copy.whatIsAZone=\u533a\u57df\u662f CloudStack&\#8482; \u90e8\u7f72\u4e2d\u6700\u5927\u7684\u7ec4\u7ec7\u5355\u4f4d\u3002\u867d\u7136\u5141\u8bb8\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u4e2d\u5b58\u5728\u591a\u4e2a\u533a\u57df\uff0c\u4f46\u662f\u4e00\u4e2a\u533a\u57df\u901a\u5e38\u4e0e\u4e00\u4e2a\u6570\u636e\u4e2d\u5fc3\u76f8\u5bf9\u5e94\u3002\u5c06\u57fa\u7840\u67b6\u6784\u7f16\u7ec4\u5230\u533a\u57df\u4e2d\u7684\u597d\u5904\u662f\u53ef\u4ee5\u63d0\u4f9b\u7269\u7406\u9694\u79bb\u548c\u5197\u4f59\u3002\u4f8b\u5982\uff0c\u6bcf\u4e2a\u533a\u57df\u90fd\u53ef\u4ee5\u62e5\u6709\u5404\u81ea\u7684\u7535\u6e90\u4f9b\u5e94\u548c\u7f51\u7edc\u4e0a\u884c\u65b9\u6848\uff0c\u5e76\u4e14\u5404\u533a\u57df\u53ef\u4ee5\u5728\u5730\u7406\u4f4d\u7f6e\u4e0a\u76f8\u9694\u5f88\u8fdc(\u867d\u7136\u5e76\u975e\u5fc5\u987b\u76f8\u9694\u5f88\u8fdc)\u3002 message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482 \u662f\u4e00\u4e2a\u8f6f\u4ef6\u5e73\u53f0\uff0c\u53ef\u5c06\u8ba1\u7b97\u8d44\u6e90\u96c6\u4e2d\u5728\u4e00\u8d77\u4ee5\u6784\u5efa\u516c\u5171\u3001\u79c1\u6709\u548c\u6df7\u5408\u57fa\u7840\u8bbe\u65bd\u5373\u670d\u52a1(IaaS)\u4e91\u3002CloudStack&\#8482 \u8d1f\u8d23\u7ba1\u7406\u7ec4\u6210\u4e91\u57fa\u7840\u67b6\u6784\u7684\u7f51\u7edc\u3001\u5b58\u50a8\u548c\u8ba1\u7b97\u8282\u70b9\u3002\u4f7f\u7528 CloudStack&\#8482 \u53ef\u4ee5\u90e8\u7f72\u3001\u7ba1\u7406\u548c\u914d\u7f6e\u4e91\u8ba1\u7b97\u73af\u5883\u3002

CloudStack&\#8482 \u901a\u8fc7\u6269\u5c55\u5546\u7528\u786c\u4ef6\u4e0a\u8fd0\u884c\u7684\u6bcf\u4e2a\u865a\u62df\u673a\u6620\u50cf\u7684\u8303\u56f4\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5b9e\u65f6\u53ef\u7528\u7684\u4e91\u57fa\u7840\u67b6\u6784\u8f6f\u4ef6\u5806\u6808\u7528\u4e8e\u4ee5\u670d\u52a1\u65b9\u5f0f\u4ea4\u4ed8\u865a\u62df\u6570\u636e\u4e2d\u5fc3\uff0c\u5373\u4ea4\u4ed8\u6784\u5efa\u3001\u90e8\u7f72\u548c\u7ba1\u7406\u591a\u5c42\u6b21\u548c\u591a\u79df\u6237\u4e91\u5e94\u7528\u7a0b\u5e8f\u5fc5\u9700\u7684\u6240\u6709\u7ec4\u4ef6\u3002\u5f00\u6e90\u7248\u672c\u548c Premium \u7248\u672c\u90fd\u5df2\u53ef\u7528\uff0c\u4e14\u63d0\u4f9b\u7684\u529f\u80fd\u51e0\u4e4e\u5b8c\u5168\u76f8\u540c\u3002 -message.installWizard.copy.whatIsPrimaryStorage=CloudStack&\#8482; \u4e91\u57fa\u7840\u67b6\u6784\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\: \u4e3b\u5b58\u50a8\u548c\u8f85\u52a9\u5b58\u50a8\u3002\u8fd9\u4e24\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\u53ef\u4ee5\u662f iSCSI \u6216 NFS \u670d\u52a1\u5668\uff0c\u4e5f\u53ef\u4ee5\u662f\u672c\u5730\u78c1\u76d8\u3002

\u4e3b\u5b58\u50a8\u4e0e\u7fa4\u96c6\u76f8\u5173\u8054\uff0c\u7528\u4e8e\u5b58\u50a8\u8be5\u7fa4\u96c6\u4e2d\u7684\u4e3b\u673a\u4e0a\u6b63\u5728\u8fd0\u884c\u7684\u6240\u6709 VM \u5bf9\u5e94\u7684\u6bcf\u4e2a\u6765\u5bbe VM \u7684\u78c1\u76d8\u5377\u3002\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u901a\u5e38\u4f4d\u4e8e\u9760\u8fd1\u4e3b\u673a\u7684\u4f4d\u7f6e\u3002 +message.installWizard.copy.whatIsPrimaryStorage=CloudStack&\#8482; \u4e91\u57fa\u7840\u67b6\u6784\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u7c7b\u578b\u7684\u5b58\u50a8: \u4e3b\u5b58\u50a8\u548c\u8f85\u52a9\u5b58\u50a8\u3002\u8fd9\u4e24\u79cd\u7c7b\u578b\u7684\u5b58\u50a8\u53ef\u4ee5\u662f iSCSI \u6216 NFS \u670d\u52a1\u5668\uff0c\u4e5f\u53ef\u4ee5\u662f\u672c\u5730\u78c1\u76d8\u3002

\u4e3b\u5b58\u50a8\u4e0e\u7fa4\u96c6\u76f8\u5173\u8054\uff0c\u7528\u4e8e\u5b58\u50a8\u8be5\u7fa4\u96c6\u4e2d\u7684\u4e3b\u673a\u4e0a\u6b63\u5728\u8fd0\u884c\u7684\u6240\u6709 VM \u5bf9\u5e94\u7684\u6bcf\u4e2a\u6765\u5bbe VM \u7684\u78c1\u76d8\u5377\u3002\u4e3b\u5b58\u50a8\u670d\u52a1\u5668\u901a\u5e38\u4f4d\u4e8e\u9760\u8fd1\u4e3b\u673a\u7684\u4f4d\u7f6e\u3002 message.installWizard.copy.whatIsSecondaryStorage=\u8f85\u52a9\u5b58\u50a8\u4e0e\u533a\u57df\u76f8\u5173\u8054\uff0c\u7528\u4e8e\u5b58\u50a8\u4ee5\u4e0b\u9879\u76ee\:
  • \u6a21\u677f - \u53ef\u7528\u4e8e\u542f\u52a8 VM \u5e76\u53ef\u4ee5\u5305\u542b\u5176\u4ed6\u914d\u7f6e\u4fe1\u606f(\u4f8b\u5982\uff0c\u5df2\u5b89\u88c5\u7684\u5e94\u7528\u7a0b\u5e8f)\u7684\u64cd\u4f5c\u7cfb\u7edf\u6620\u50cf
  • ISO \u6620\u50cf - \u53ef\u91cd\u65b0\u542f\u52a8\u6216\u4e0d\u53ef\u91cd\u65b0\u542f\u52a8\u7684\u64cd\u4f5c\u7cfb\u7edf\u6620\u50cf
  • \u78c1\u76d8\u5377\u5feb\u7167 - \u5df2\u4fdd\u5b58\u7684 VM \u6570\u636e\u526f\u672c\uff0c\u53ef\u7528\u4e8e\u6267\u884c\u6570\u636e\u6062\u590d\u6216\u521b\u5efa\u65b0\u6a21\u677f
-message.installWizard.now.building=\u73b0\u5728\u6b63\u5728\u6784\u5efa\u60a8\u7684\u4e91... +message.installWizard.now.building=\u73b0\u5728\u6b63\u5728\u6784\u5efa\u60a8\u7684\u4e91... message.installWizard.tooltip.addCluster.name=\u7fa4\u96c6\u7684\u540d\u79f0\u3002\u6b64\u540d\u79f0\u53ef\u4ee5\u662f\u60a8\u9009\u62e9\u7684\u6587\u672c\uff0c\u4e14\u672a\u7531 CloudStack \u4f7f\u7528\u3002 message.installWizard.tooltip.addHost.hostname=\u4e3b\u673a\u7684 DNS \u540d\u79f0\u6216 IP \u5730\u5740\u3002 message.installWizard.tooltip.addHost.password=\u6b64\u4e3a\u4e0a\u8ff0\u7528\u6237\u7684\u5bc6\u7801(\u6765\u81ea XenServer \u5b89\u88c5)\u3002 @@ -1391,7 +1411,7 @@ message.instanceWizard.noTemplates=\u60a8\u6ca1\u6709\u4efb\u4f55\u53ef\u7528\u6 message.ip.address.changed=\u60a8\u7684 IP \u5730\u5740\u53ef\u80fd\u5df2\u53d1\u751f\u53d8\u5316\uff1b\u662f\u5426\u8981\u5237\u65b0\u6b64\u5217\u8868? \u8bf7\u6ce8\u610f\uff0c\u5237\u65b0\u6b64\u5217\u8868\u65f6\uff0c\u201c\u8be6\u7ec6\u4fe1\u606f\u201d\u7a97\u683c\u5c06\u5173\u95ed\u3002 message.iso.desc=\u5305\u542b\u64cd\u4f5c\u7cfb\u7edf\u7684\u6570\u636e\u6216\u53ef\u542f\u52a8\u4ecb\u8d28\u7684\u78c1\u76d8\u6620\u50cf message.join.project=\u60a8\u73b0\u5728\u5df2\u52a0\u5165\u4e86\u4e00\u4e2a\u9879\u76ee\u3002\u8bf7\u5207\u6362\u5230\u201c\u9879\u76ee\u89c6\u56fe\u201d\u4ee5\u67e5\u770b\u9879\u76ee\u3002 -message.launch.vm.on.private.network=\u662f\u5426\u8981\u5728\u60a8\u7684\u79c1\u4eba\u4e13\u7528\u7f51\u7edc\u4e2d\u542f\u52a8\u5b9e\u4f8b? +message.launch.vm.on.private.network=\u662f\u5426\u8981\u5728\u60a8\u7684\u79c1\u4eba\u4e13\u7528\u7f51\u7edc\u4e2d\u542f\u52a8\u5b9e\u4f8b? message.launch.zone=\u533a\u57df\u5df2\u51c6\u5907\u5c31\u7eea\uff0c\u53ef\u968f\u65f6\u542f\u52a8\uff1b\u8bf7\u7ee7\u7eed\u6267\u884c\u4e0b\u4e00\u6b65\u9aa4\u3002 message.lock.account=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u9501\u5b9a\u6b64\u5e10\u6237\u3002\u901a\u8fc7\u9501\u5b9a\u6b64\u5e10\u6237\uff0c\u6b64\u5e10\u6237\u7684\u6240\u6709\u7528\u6237\u5c06\u4e0d\u518d\u80fd\u591f\u7ba1\u7406\u5404\u81ea\u7684\u4e91\u8d44\u6e90\uff0c\u4f46\u4ecd\u7136\u53ef\u4ee5\u8bbf\u95ee\u73b0\u6709\u8d44\u6e90\u3002 message.migrate.instance.confirm=\u8bf7\u786e\u8ba4\u8981\u5c06\u865a\u62df\u5b9e\u4f8b\u8fc1\u79fb\u5230\u7684\u4e3b\u673a\u3002 @@ -1422,14 +1442,14 @@ message.project.invite.sent=\u53d1\u9001\u7ed9\u7528\u6237\u7684\u9080\u8bf7\uff message.public.traffic.in.advanced.zone=\u4e91\u4e2d\u7684 VM \u8bbf\u95ee Internet \u65f6\u5c06\u751f\u6210\u516c\u5171\u6d41\u91cf\uff0c\u4f46\u5fc5\u987b\u5206\u914d\u53ef\u516c\u5f00\u8bbf\u95ee\u7684 IP \u624d\u80fd\u5b9e\u73b0\u3002\u6700\u7ec8\u7528\u6237\u53ef\u4ee5\u4f7f\u7528 CloudStack UI \u83b7\u53d6\u8fd9\u4e9b IP\uff0c\u4ee5\u5728\u5176\u6765\u5bbe\u7f51\u7edc\u4e0e\u516c\u7528\u7f51\u7edc\u4e4b\u95f4\u6267\u884c NAT\u3002

\u8bf7\u81f3\u5c11\u4e3a Internet \u6d41\u91cf\u63d0\u4f9b\u4e00\u4e2a IP \u5730\u5740\u8303\u56f4\u3002 message.public.traffic.in.basic.zone=\u4e91\u4e2d\u7684 VM \u8bbf\u95ee Internet \u6216\u901a\u8fc7 Internet \u5411\u5ba2\u6237\u7aef\u63d0\u4f9b\u670d\u52a1\u65f6\u5c06\u751f\u6210\u516c\u5171\u6d41\u91cf\uff0c\u4f46\u5fc5\u987b\u5206\u914d\u53ef\u516c\u5f00\u8bbf\u95ee\u7684 IP \u624d\u80fd\u5b9e\u73b0\u3002\u521b\u5efa\u5b9e\u4f8b\u65f6\uff0c\u5c06\u628a\u8fd9\u4e00\u7ec4\u516c\u7528 IP \u4e2d\u7684 IP (\u6765\u5bbe IP \u5730\u5740\u9664\u5916)\u5206\u914d\u7ed9\u6b64\u5b9e\u4f8b\u3002\u9759\u6001 1-1 NAT \u5c06\u5728\u516c\u7528 IP \u4e0e\u6765\u5bbe IP \u4e4b\u95f4\u81ea\u52a8\u8bbe\u7f6e\u3002\u6700\u7ec8\u7528\u6237\u8fd8\u53ef\u4ee5\u4f7f\u7528 CloudStack UI \u83b7\u53d6\u5176\u4ed6 IP\uff0c\u4ee5\u5728\u5176\u5b9e\u4f8b\u4e0e\u516c\u7528 IP \u4e4b\u95f4\u6267\u884c\u9759\u6001 NAT\u3002 message.redirecting.region=\u6b63\u5728\u91cd\u5b9a\u5411\u5230\u533a\u57df... -message.remove.region=\u4f60\u786e\u5b9a\u60f3\u8981\u4ece\u7ba1\u7406\u670d\u52a1\u5668\u5220\u9664\u6b64\u533a\u57df\u5417? +message.remove.region=\u662f\u5426\u786e\u5b9e\u8981\u4ece\u6b64\u7ba1\u7406\u670d\u52a1\u5668\u4e2d\u5220\u9664\u6b64\u533a\u57df? message.remove.vpc=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 VPC message.remove.vpn.access=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u4ee5\u4e0b\u7528\u6237\u7684 VPN \u8bbf\u95ee\u3002 message.reset.password.warning.notPasswordEnabled=\u521b\u5efa\u6b64\u5b9e\u4f8b\u7684\u6a21\u677f\u65f6\u672a\u542f\u7528\u5bc6\u7801 message.reset.password.warning.notStopped=\u5fc5\u987b\u5148\u505c\u6b62\u60a8\u7684\u5b9e\u4f8b\uff0c\u624d\u80fd\u5c1d\u8bd5\u66f4\u6539\u5176\u5f53\u524d\u5bc6\u7801 message.reset.VPN.connection=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u91cd\u7f6e VPN \u8fde\u63a5 message.restart.mgmt.server=\u8bf7\u91cd\u65b0\u542f\u52a8\u7ba1\u7406\u670d\u52a1\u5668\u4ee5\u4f7f\u60a8\u7684\u65b0\u8bbe\u7f6e\u751f\u6548\u3002 -message.restart.mgmt.usage.server=\u4e3a\u4e86\u4f7f\u4f60\u7684\u65b0\u8bbe\u7f6e\u751f\u6548\uff0c\u8bf7\u91cd\u65b0\u542f\u52a8\u4f60\u7684\u7ba1\u7406\u670d\u52a1\u5668\u548c\u4f7f\u7528\u670d\u52a1\u5668\u3002 +message.restart.mgmt.usage.server=\u8bf7\u91cd\u65b0\u542f\u52a8\u7ba1\u7406\u670d\u52a1\u5668\u548c\u4f7f\u7528\u670d\u52a1\u5668\u4ee5\u4f7f\u60a8\u7684\u65b0\u8bbe\u7f6e\u751f\u6548\u3002 message.restart.network=\u6b64\u7f51\u7edc\u63d0\u4f9b\u7684\u6240\u6709\u670d\u52a1\u90fd\u5c06\u4e2d\u65ad\u3002\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u91cd\u65b0\u542f\u52a8\u6b64\u7f51\u7edc\u3002 message.restart.vpc=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u91cd\u65b0\u542f\u52a8 VPC message.security.group.usage=(\u6309\u4f4f Ctrl \u952e\u5e76\u5355\u51fb\u9f20\u6807\u53ef\u9009\u62e9\u6240\u6709\u9002\u7528\u7684\u5b89\u5168\u7ec4) @@ -1473,13 +1493,13 @@ message.vm.create.template.confirm=\u521b\u5efa\u6a21\u677f\u5c06\u81ea\u52a8\u9 message.vm.review.launch=\u8bf7\u5148\u6838\u5bf9\u4ee5\u4e0b\u4fe1\u606f\uff0c\u786e\u8ba4\u60a8\u7684\u865a\u62df\u5b9e\u4f8b\u6b63\u786e\u65e0\u8bef\uff0c\u7136\u540e\u518d\u542f\u52a8\u3002 message.volume.create.template.confirm=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u4e3a\u6b64\u78c1\u76d8\u5377\u521b\u5efa\u4e00\u4e2a\u6a21\u677f\u3002\u521b\u5efa\u6a21\u677f\u53ef\u80fd\u9700\u8981\u51e0\u5206\u949f\u5230\u66f4\u957f\u7684\u65f6\u95f4\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u5377\u7684\u5927\u5c0f\u3002 message.you.must.have.at.least.one.physical.network=\u60a8\u5fc5\u987b\u81f3\u5c11\u62e5\u6709\u4e00\u4e2a\u7269\u7406\u7f51\u7edc -message.Zone.creation.complete=\u5df2\u5b8c\u6210\u521b\u5efa\u533a\u57df message.zone.creation.complete.would.you.like.to.enable.this.zone=\u5df2\u5b8c\u6210\u521b\u5efa\u533a\u57df\u3002\u662f\u5426\u8981\u542f\u7528\u6b64\u533a\u57df? +message.Zone.creation.complete=\u5df2\u5b8c\u6210\u521b\u5efa\u533a\u57df message.zone.no.network.selection=\u6240\u9009\u533a\u57df\u65e0\u4efb\u4f55\u7f51\u7edc\u9009\u9879\u3002 message.zone.step.1.desc=\u8bf7\u4e3a\u60a8\u7684\u533a\u57df\u9009\u62e9\u4e00\u79cd\u7f51\u7edc\u6a21\u5f0f\u3002 message.zone.step.2.desc=\u8bf7\u8f93\u5165\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u533a\u57df message.zone.step.3.desc=\u8bf7\u8f93\u5165\u4ee5\u4e0b\u4fe1\u606f\u4ee5\u6dfb\u52a0\u4e00\u4e2a\u65b0\u63d0\u4f9b\u70b9 -message.zoneWizard.enable.local.storage=\u8b66\u544a\: \u5982\u679c\u4e3a\u6b64\u533a\u57df\u542f\u7528\u4e86\u672c\u5730\u5b58\u50a8\uff0c\u5219\u5fc5\u987b\u6267\u884c\u4ee5\u4e0b\u64cd\u4f5c\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u5e0c\u671b\u542f\u52a8\u7cfb\u7edf VM \u7684\u4f4d\u7f6e\:

1. \u5982\u679c\u8981\u5728\u4e3b\u5b58\u50a8\u4e2d\u542f\u52a8\u7cfb\u7edf VM\uff0c\u5219\u9700\u8981\u5728\u521b\u5efa\u540e\u5c06\u4e3b\u5b58\u50a8\u6dfb\u52a0\u5230\u6b64\u533a\u57df\u4e2d\u3002\u6b64\u5916\uff0c\u8fd8\u5fc5\u987b\u542f\u52a8\u5904\u4e8e\u7981\u7528\u72b6\u6001\u7684\u533a\u57df\u3002

2. \u5982\u679c\u8981\u5728\u672c\u5730\u5b58\u50a8\u4e2d\u542f\u52a8\u7cfb\u7edf VM\uff0c\u5219\u9700\u8981\u5148\u5c06 system.vm.use.local.storage \u8bbe\u7f6e\u4e3a True\uff0c\u7136\u540e\u518d\u542f\u7528\u6b64\u533a\u57df\u3002


\u662f\u5426\u8981\u7ee7\u7eed? +message.zoneWizard.enable.local.storage=\u8b66\u544a\: \u5982\u679c\u4e3a\u6b64\u533a\u57df\u542f\u7528\u4e86\u672c\u5730\u5b58\u50a8\uff0c\u5219\u5fc5\u987b\u6267\u884c\u4ee5\u4e0b\u64cd\u4f5c\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u60a8\u5e0c\u671b\u542f\u52a8\u7cfb\u7edf VM \u7684\u4f4d\u7f6e\:

1. \u5982\u679c\u9700\u8981\u5728\u4e3b\u5b58\u50a8\u4e2d\u542f\u52a8\u7cfb\u7edf VM\uff0c\u5219\u5fc5\u987b\u5728\u5b8c\u6210\u521b\u5efa\u540e\u5c06\u4e3b\u5b58\u50a8\u6dfb\u52a0\u5230\u6b64\u533a\u57df\u4e2d\u3002

2. \u5982\u679c\u9700\u8981\u5728\u672c\u5730\u5b58\u50a8\u4e2d\u542f\u52a8\u7cfb\u7edf VM\uff0c\u5219\u5fc5\u987b\u5c06 system.vm.use.local.storage \u8bbe\u7f6e\u4e3a true\u3002


\u662f\u5426\u8981\u7ee7\u7eed? mode=\u6a21\u5f0f network.rate=\u7f51\u7edc\u901f\u7387 notification.reboot.instance=\u91cd\u65b0\u542f\u52a8\u5b9e\u4f8b @@ -1497,14 +1517,14 @@ state.Creating=\u6b63\u5728\u521b\u5efa state.Declined=\u5df2\u62d2\u7edd state.Destroyed=\u5df2\u9500\u6bc1 state.Disabled=\u5df2\u7981\u7528 -state.enabled=\u5df2\u542f\u7528 state.Enabled=\u5df2\u542f\u7528 +state.enabled=\u5df2\u542f\u7528 state.Error=\u9519\u8bef state.Expunging=\u6b63\u5728\u5220\u9664 state.Migrating=\u6b63\u5728\u8fc1\u79fb state.Pending=\u5f85\u5b9a -state.ready=\u5df2\u5c31\u7eea state.Ready=\u5df2\u5c31\u7eea +state.ready=\u5df2\u5c31\u7eea state.Running=\u6b63\u5728\u8fd0\u884c state.Starting=\u6b63\u5728\u542f\u52a8 state.Stopped=\u5df2\u505c\u6b62 diff --git a/client/pom.xml b/client/pom.xml index ab758eb2a67..24f51fbee2f 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -30,7 +30,7 @@ cloud-plugin-acl-static-role-based ${project.version} - + org.apache.cloudstack cloud-plugin-dedicated-resources ${project.version} @@ -105,6 +105,11 @@ cloud-plugin-hypervisor-baremetal ${project.version} + + org.apache.cloudstack + cloud-plugin-hypervisor-ucs + ${project.version} + org.apache.cloudstack cloud-plugin-hypervisor-ovm @@ -211,7 +216,7 @@ org.apache.cloudstack - cloud-engine-storage-backup + cloud-engine-storage-cache ${project.version} @@ -221,7 +226,7 @@ org.apache.cloudstack - cloud-engine-storage-imagemotion + cloud-engine-storage-datamotion ${project.version} @@ -244,6 +249,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 d3b53697dca..627c65560fe 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -181,8 +181,6 @@ - - @@ -196,7 +194,6 @@ - @@ -219,6 +216,7 @@ + @@ -229,8 +227,13 @@ - - + + + + + + + @@ -282,7 +285,7 @@ - + @@ -310,7 +313,6 @@ - @@ -364,7 +366,6 @@ - @@ -727,9 +728,10 @@ + + + - - @@ -746,17 +748,15 @@ - + + - - - - - + + - + @@ -773,7 +773,6 @@ - @@ -799,8 +798,12 @@ + + + + @@ -839,7 +842,6 @@ Baremetal components --> - diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 5eccf366c66..648b69d5be3 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -249,6 +249,13 @@ listSwifts=1 addS3=1 listS3s=1 +#### image store commands +addImageStore=1 +listImageStores=1 +deleteImageStore=1 +createCacheStore=1 +listCacheStores=1 + #### host commands addHost=3 addCluster=1 @@ -595,6 +602,9 @@ revertToVMSnapshot=15 #### Baremetal commands addBaremetalHost=1 +addBaremetalPxeKickStartServer=1 +addBaremetalPxePingServer=1 +addBaremetalDhcp=1 #### New Load Balancer commands createLoadBalancer=15 diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in index 93ef21f679b..7563d69d20e 100644 --- a/client/tomcatconf/componentContext.xml.in +++ b/client/tomcatconf/componentContext.xml.in @@ -116,11 +116,7 @@ - - - @@ -156,9 +152,7 @@ - @@ -208,9 +202,7 @@ - @@ -243,11 +235,9 @@ - diff --git a/client/tomcatconf/log4j-cloud.xml.in b/client/tomcatconf/log4j-cloud.xml.in index 0e7f004eb80..503ba8e76a1 100755 --- a/client/tomcatconf/log4j-cloud.xml.in +++ b/client/tomcatconf/log4j-cloud.xml.in @@ -123,6 +123,10 @@ under the License. + + + + @@ -132,6 +136,10 @@ under the License. + + + + diff --git a/client/tomcatconf/nonossComponentContext.xml.in b/client/tomcatconf/nonossComponentContext.xml.in index 143aa220cfc..62685e965e5 100644 --- a/client/tomcatconf/nonossComponentContext.xml.in +++ b/client/tomcatconf/nonossComponentContext.xml.in @@ -215,9 +215,7 @@ - @@ -256,9 +254,7 @@ - @@ -308,9 +304,7 @@ - @@ -349,11 +343,9 @@ - diff --git a/core/src/com/cloud/agent/api/AttachVolumeCommand.java b/core/src/com/cloud/agent/api/AttachVolumeCommand.java index 302b8f80af3..2658262a6cd 100644 --- a/core/src/com/cloud/agent/api/AttachVolumeCommand.java +++ b/core/src/com/cloud/agent/api/AttachVolumeCommand.java @@ -29,6 +29,10 @@ public class AttachVolumeCommand extends Command { String volumeName; Long deviceId; String chainInfo; + Long bytesReadRate; + Long bytesWriteRate; + Long iopsReadRate; + Long iopsWriteRate; protected AttachVolumeCommand() { } @@ -96,4 +100,36 @@ public class AttachVolumeCommand extends Command { public String getChainInfo() { return chainInfo; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } 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/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/core/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java b/core/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java deleted file mode 100644 index 3d62c507b89..00000000000 --- a/core/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/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java b/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java deleted file mode 100644 index 128df84c729..00000000000 --- a/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java +++ /dev/null @@ -1,96 +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.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 SwiftTO swift; - private S3TO s3; - private Boolean all; - - public SwiftTO getSwift() { - return swift; - } - - public Boolean isAll() { - return all; - } - - public void setAll(Boolean all) { - this.all = all; - } - - public void setSwift(SwiftTO swift) { - this.swift = swift; - } - - public S3TO getS3() { - return s3; - } - - 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(StoragePool pool, - SwiftTO swift, - S3TO s3, - String secondaryStoragePoolURL, - Long dcId, - Long accountId, - Long volumeId, - String backupUUID, Boolean all) - { - super(pool, secondaryStoragePoolURL, backupUUID, null, dcId, accountId, volumeId); - setSwift(swift); - this.s3 = s3; - setAll(all); - } -} 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/core/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java b/core/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java deleted file mode 100644 index 278669b2c97..00000000000 --- a/core/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/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/core/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java b/core/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java index df77985248f..ed7043a8ec4 100644 --- a/core/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java +++ b/core/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/core/src/com/cloud/agent/api/ScaleVmCommand.java b/core/src/com/cloud/agent/api/ScaleVmCommand.java index b3614856361..83cdcac2615 100644 --- a/core/src/com/cloud/agent/api/ScaleVmCommand.java +++ b/core/src/com/cloud/agent/api/ScaleVmCommand.java @@ -41,7 +41,7 @@ public class ScaleVmCommand extends Command { } public ScaleVmCommand(String vmName, int cpus, - Integer minSpeed, Integer maxSpeed, long minRam, long maxRam, boolean limitCpuUse) { + Integer minSpeed, Integer maxSpeed, long minRam, long maxRam, boolean limitCpuUse, boolean isDynamicallyScalable) { super(); this.vmName = vmName; this.cpus = cpus; @@ -50,6 +50,7 @@ public class ScaleVmCommand extends Command { this.minRam = minRam; this.maxRam = maxRam; this.vm = new VirtualMachineTO(1L, vmName, null, cpus, minSpeed, maxSpeed, minRam, maxRam, null, null, false, limitCpuUse, null); + vm.setEnableDynamicallyScaleVm(isDynamicallyScalable); /*vm.setName(vmName); vm.setCpus(cpus); vm.setRam(minRam, maxRam);*/ diff --git a/core/src/com/cloud/agent/api/SecStorageSetupCommand.java b/core/src/com/cloud/agent/api/SecStorageSetupCommand.java index 50c06cffa43..b1f32348baa 100644 --- a/core/src/com/cloud/agent/api/SecStorageSetupCommand.java +++ b/core/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/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/agent/api/StartCommand.java b/core/src/com/cloud/agent/api/StartCommand.java index ec707d6e851..308730ab5b7 100644 --- a/core/src/com/cloud/agent/api/StartCommand.java +++ b/core/src/com/cloud/agent/api/StartCommand.java @@ -24,6 +24,7 @@ import com.cloud.host.Host; public class StartCommand extends Command { VirtualMachineTO vm; String hostIp; + boolean executeInSequence = false; public VirtualMachineTO getVirtualMachine() { return vm; @@ -31,19 +32,16 @@ public class StartCommand extends Command { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } protected StartCommand() { } - public StartCommand(VirtualMachineTO vm) { - this.vm = vm; - } - - public StartCommand(VirtualMachineTO vm, Host host) { + public StartCommand(VirtualMachineTO vm, Host host, boolean executeInSequence) { this.vm = vm; this.hostIp = host.getPrivateIpAddress(); + this.executeInSequence = executeInSequence; } public String getHostIp() { diff --git a/core/src/com/cloud/agent/api/StartupStorageCommand.java b/core/src/com/cloud/agent/api/StartupStorageCommand.java index 3c3b058ce39..52ed3ffdff3 100755 --- a/core/src/com/cloud/agent/api/StartupStorageCommand.java +++ b/core/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/core/src/com/cloud/agent/api/StopCommand.java b/core/src/com/cloud/agent/api/StopCommand.java index 7d3fd43060e..e0dde7d23be 100755 --- a/core/src/com/cloud/agent/api/StopCommand.java +++ b/core/src/com/cloud/agent/api/StopCommand.java @@ -24,11 +24,12 @@ public class StopCommand extends RebootCommand { private String urlPort=null; private String publicConsoleProxyIpAddress=null; private boolean cleanupOnly; + boolean executeInSequence = false; protected StopCommand() { } - public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress, boolean cleanupOnly) { + public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress, boolean cleanupOnly, boolean executeInSequence) { super(vm); this.isProxy = isProxy; this.urlPort = urlPort; @@ -36,21 +37,24 @@ public class StopCommand extends RebootCommand { this.cleanupOnly = cleanupOnly; } - public StopCommand(VirtualMachine vm, String vnet) { + public StopCommand(VirtualMachine vm, String vnet, boolean executeInSequence) { super(vm); this.vnet = vnet; + this.executeInSequence = executeInSequence; } public boolean isCleanupOnly() { return cleanupOnly; } - public StopCommand(VirtualMachine vm) { + public StopCommand(VirtualMachine vm, boolean executeInSequence) { super(vm); + this.executeInSequence = executeInSequence; } - public StopCommand(String vmName) { + public StopCommand(String vmName, boolean executeInSequence) { super(vmName); + this.executeInSequence = executeInSequence; } public String getVnet() { @@ -59,7 +63,7 @@ public class StopCommand extends RebootCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public boolean isProxy() { diff --git a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java index fd8d84c8c3a..d51ea5e70b5 100644 --- a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java +++ b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java @@ -32,6 +32,7 @@ public class DhcpEntryCommand extends NetworkElementCommand { String ip6Gateway; String duid; private boolean isDefault; + boolean executeInSequence = false; protected DhcpEntryCommand() { @@ -39,19 +40,20 @@ public class DhcpEntryCommand extends NetworkElementCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address) { + public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, boolean executeInSequence) { this.vmMac = vmMac; this.vmIpAddress = vmIpAddress; this.vmName = vmName; this.vmIp6Address = vmIp6Address; this.setDefault(true); + this.executeInSequence = executeInSequence; } - public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway) { - this(vmMac, vmIpAddress, vmName, vmIp6Address); + public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway, boolean executeInSequence) { + this(vmMac, vmIpAddress, vmName, vmIp6Address, executeInSequence); this.dns = dns; this.gateway = gateway; } diff --git a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java index ddb7ac87386..843d213896e 100644 --- a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java +++ b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java @@ -33,6 +33,7 @@ public abstract class NetworkElementCommand extends Command { public static final String ZONE_NETWORK_TYPE = "zone.network.type"; public static final String GUEST_BRIDGE = "guest.bridge"; public static final String VPC_PRIVATE_GATEWAY = "vpc.gateway.private"; + public static final String FIREWALL_EGRESS_DEFAULT = "firewall.egress.default"; protected NetworkElementCommand() { diff --git a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java index 6dac1488e11..c77dbf60987 100644 --- a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java +++ b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java @@ -22,19 +22,21 @@ public class SavePasswordCommand extends NetworkElementCommand { String password; String vmIpAddress; String vmName; + boolean executeInSequence = false; protected SavePasswordCommand() { } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public SavePasswordCommand(String password, String vmIpAddress, String vmName) { + public SavePasswordCommand(String password, String vmIpAddress, String vmName, boolean executeInSequence) { this.password = password; this.vmIpAddress = vmIpAddress; this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getPassword() { diff --git a/core/src/com/cloud/agent/api/routing/UserDataCommand.java b/core/src/com/cloud/agent/api/routing/UserDataCommand.java index f7b38c8c364..cf360023abc 100644 --- a/core/src/com/cloud/agent/api/routing/UserDataCommand.java +++ b/core/src/com/cloud/agent/api/routing/UserDataCommand.java @@ -23,6 +23,7 @@ public class UserDataCommand extends NetworkElementCommand { String vmIpAddress; String routerPrivateIpAddress; String vmName; + boolean executeInSequence = false; protected UserDataCommand() { @@ -30,14 +31,15 @@ public class UserDataCommand extends NetworkElementCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName) { + public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName, boolean executeInSequence) { this.userData = userData; this.vmIpAddress = vmIpAddress; this.routerPrivateIpAddress = routerPrivateIpAddress; this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getRouterPrivateIpAddress() { diff --git a/core/src/com/cloud/agent/api/routing/VmDataCommand.java b/core/src/com/cloud/agent/api/routing/VmDataCommand.java index df882554479..861f7006432 100644 --- a/core/src/com/cloud/agent/api/routing/VmDataCommand.java +++ b/core/src/com/cloud/agent/api/routing/VmDataCommand.java @@ -28,27 +28,29 @@ public class VmDataCommand extends NetworkElementCommand { String vmName; @LogLevel(Log4jLevel.Trace) List vmData; + boolean executeInSequence = false; protected VmDataCommand() { } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public VmDataCommand(String vmIpAddress) { - this(vmIpAddress, null); + public VmDataCommand(String vmIpAddress, boolean executeInSequence) { + this(vmIpAddress, null, executeInSequence); } public String getVmName() { return vmName; } - public VmDataCommand(String vmIpAddress, String vmName) { + public VmDataCommand(String vmIpAddress, String vmName, boolean executeInSequence) { this.vmName = vmName; this.vmIpAddress = vmIpAddress; this.vmData = new ArrayList(); + this.executeInSequence = executeInSequence; } diff --git a/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java b/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java index 04b3d4360d5..248a41902ac 100644 --- a/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java +++ b/core/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/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/CopyVolumeCommand.java b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java index 3d05e9ba69c..1acf2cc13f1 100644 --- a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java +++ b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java @@ -28,22 +28,24 @@ public class CopyVolumeCommand extends Command { String secondaryStorageURL; boolean toSecondaryStorage; String vmName; + boolean executeInSequence = false; public CopyVolumeCommand() { } - public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait) { + public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait, boolean executeInSequence) { this.volumeId = volumeId; this.volumePath = volumePath; this.pool = new StorageFilerTO(pool); this.secondaryStorageURL = secondaryStorageURL; this.toSecondaryStorage = toSecondaryStorage; setWait(wait); + this.executeInSequence = executeInSequence; } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public String getVolumePath() { 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/CreateCommand.java b/core/src/com/cloud/agent/api/storage/CreateCommand.java index fd0375aa6e7..900abfd744e 100644 --- a/core/src/com/cloud/agent/api/storage/CreateCommand.java +++ b/core/src/com/cloud/agent/api/storage/CreateCommand.java @@ -26,6 +26,7 @@ public class CreateCommand extends Command { private StorageFilerTO pool; private DiskProfile diskCharacteristics; private String templateUrl; + boolean executeInSequence = false; protected CreateCommand() { super(); @@ -33,44 +34,47 @@ public class CreateCommand extends Command { /** * Construction for template based volumes. - * - * @param vol - * @param vm * @param diskCharacteristics * @param templateUrl * @param pool + * @param executeInSequence TODO + * @param vol + * @param vm */ - public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool) { - this(diskCharacteristics, pool); + public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool, boolean executeInSequence) { + this(diskCharacteristics, pool, executeInSequence); this.templateUrl = templateUrl; + this.executeInSequence = executeInSequence; } /** * Construction for regular volumes. - * - * @param vol - * @param vm * @param diskCharacteristics * @param pool + * @param executeInSequence TODO + * @param vol + * @param vm */ - public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool) { + public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool, boolean executeInSequence) { this.volId = diskCharacteristics.getVolumeId(); this.diskCharacteristics = diskCharacteristics; this.pool = pool; this.templateUrl = null; + this.executeInSequence = executeInSequence; } - public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool) { - this(diskCharacteristics, templateUrl, new StorageFilerTO(pool)); + public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool, boolean executeInSequence) { + this(diskCharacteristics, templateUrl, new StorageFilerTO(pool), executeInSequence); } - public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool) { - this(diskCharacteristics, new StorageFilerTO(pool)); + public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool, boolean executeInSequence) { + this(diskCharacteristics, new StorageFilerTO(pool), executeInSequence); + this.executeInSequence = executeInSequence; } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public String getTemplateUrl() { 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 a4e2e255001..a3542cf6083 100644 --- a/core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java +++ b/core/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() { - + super(); } - 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/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java b/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java index da25ed56bf3..e5339f2982d 100644 --- a/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java +++ b/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java @@ -16,39 +16,32 @@ // 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.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; + //private String secUrl; public ListTemplateCommand() { } - public ListTemplateCommand(String secUrl) { - this.secUrl = secUrl; - this.swift = null; + public ListTemplateCommand(DataStoreTO store) { + this.store = store; +// this.secUrl = url; } - public ListTemplateCommand(SwiftTO swift) { - this.secUrl = null; - this.swift = swift; - } - @Override public boolean executeInSequence() { return true; } - public String getSecUrl() { - return secUrl; + + public DataStoreTO getDataStore() { + return store; } - public SwiftTO getSwift() { - return swift; - } + // public String getSecUrl() { + // return secUrl; + // } } diff --git a/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java b/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java index 6bbb2e82c33..9995d4b715e 100755 --- a/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java +++ b/core/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() { - + super(); } - 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/core/src/com/cloud/agent/api/storage/ListVolumeCommand.java b/core/src/com/cloud/agent/api/storage/ListVolumeCommand.java index 63c5b621c6e..0de44defdb1 100755 --- a/core/src/com/cloud/agent/api/storage/ListVolumeCommand.java +++ b/core/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/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/PrimaryStorageDownloadCommand.java b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java index 8d955bb1c63..b0d0fdf87eb 100644 --- a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java +++ b/core/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/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); diff --git a/core/src/com/cloud/agent/api/storage/UploadCommand.java b/core/src/com/cloud/agent/api/storage/UploadCommand.java index 473bd5b75ac..9b893e2abd5 100644 --- a/core/src/com/cloud/agent/api/storage/UploadCommand.java +++ b/core/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/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index dae1c8591f4..4f0cceca4a1 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -224,6 +224,7 @@ public class VirtualRoutingResource implements Manager { results[i] = "Failed"; } String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); if (routerIp == null) { return new SetFirewallRulesAnswer(cmd, false, results); @@ -239,6 +240,13 @@ public class VirtualRoutingResource implements Manager { if (trafficType == FirewallRule.TrafficType.Egress){ command.add("-E"); + if (egressDefault.equals("true")) { + command.add("-P ", "1"); + } else if (egressDefault.equals("System")) { + command.add("-P ", "2"); + } else { + command.add("-P ", "0"); + } } StringBuilder sb = new StringBuilder(); 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); 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/hypervisor/hyperv/resource/HypervResource.java b/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java index 91ba4f68f48..ca26bffc571 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; @@ -766,7 +766,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/serializer/GsonHelper.java b/core/src/com/cloud/serializer/GsonHelper.java index 8b2dcb0e928..54b6b171712 100644 --- a/core/src/com/cloud/serializer/GsonHelper.java +++ b/core/src/com/cloud/serializer/GsonHelper.java @@ -25,7 +25,10 @@ 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; 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(); @@ -61,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/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/core/src/com/cloud/storage/resource/StorageProcessor.java b/core/src/com/cloud/storage/resource/StorageProcessor.java new file mode 100644 index 00000000000..ca441edcb79 --- /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; + +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); + public Answer createVolumeFromSnapshot(CopyCommand cmd); + public Answer deleteSnapshot(DeleteCommand cmd); +} diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageOrchestrator.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java similarity index 75% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/ImageOrchestrator.java rename to core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java index e4141f3fa00..5ac601e38a9 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageOrchestrator.java +++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java @@ -16,14 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image; +package com.cloud.storage.resource; -public interface ImageOrchestrator { - void registerTemplate(long templateId); +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; - void registerSnapshot(long snapshotId); +import com.cloud.agent.api.Answer; - void registerVolume(long volumeId); - - void registerIso(long isoId); +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..23ccd318253 --- /dev/null +++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java @@ -0,0 +1,139 @@ +/* + * 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); + } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.VOLUME) { + return processor.createVolumeFromSnapshot(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 if (data.getObjectType() == DataObjectType.SNAPSHOT) { + answer = processor.deleteSnapshot(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/core/src/com/cloud/storage/template/HttpTemplateDownloader.java b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java index c8aac27da8c..d87dd68bb81 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,11 +46,11 @@ 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; +import com.cloud.utils.UriUtils; /** * Download a template file using HTTP @@ -79,7 +80,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 +89,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 +115,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { return false; } }; - + try { this.request = new GetMethod(downloadUrl); this.request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler); @@ -122,14 +123,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); - + Pair hostAndPort = UriUtils.validateUrl(downloadUrl); + if (proxy != null) { client.getHostConfiguration().setProxy(proxy.getHost(), proxy.getPort()); if (proxy.getUserName() != null) { @@ -144,7 +145,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,47 +158,8 @@ public class HttpTemplateDownloader implements TemplateDownloader { 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; - } - - 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) { @@ -211,17 +173,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 +197,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; @@ -262,26 +224,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; @@ -305,7 +267,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; @@ -343,8 +305,8 @@ public class HttpTemplateDownloader implements TemplateDownloader { public long getDownloadTime() { return downloadTime; } - - + + public long getDownloadedBytes() { return totalBytes; } @@ -382,7 +344,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { if (remoteSize == 0) { return 0; } - + return (int)(100.0*totalBytes/remoteSize); } @@ -395,7 +357,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { errorString = "Failed to install: " + t.getMessage(); status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; } - + } @Override @@ -431,10 +393,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 new file mode 100644 index 00000000000..340e0dba868 --- /dev/null +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -0,0 +1,418 @@ +// 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.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; +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.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; +import com.cloud.utils.S3Utils; +import com.cloud.utils.UriUtils; + +/** + * 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; + private S3TO s3; + private boolean inited = true; + + 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); + + 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); + 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); + } + } + + @Override + public long download(boolean resume, DownloadCompleteCallback callback) { + switch (status) { + case ABORTED: + case UNRECOVERABLE_ERROR: + case DOWNLOAD_FINISHED: + return 0; + default: + + } + + 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; + } + } else { + remoteSize2 = Long.parseLong(contentLengthHeader.getValue()); + } + + if (remoteSize == 0) { + remoteSize = remoteSize2; + } + + 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 = 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()); + + 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); + if ( contentType != null ){ + metadata.setContentType(contentType); + } + 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 + 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(); + + // 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)"; + } 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) { + // 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(); + } 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); + } + } + 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.maxTemplateSizeInByte; + } + + @Override + public void setDownloadError(String error) { + errorString = error; + } + + @Override + public boolean isInited() { + return inited; + } + + public ResourceType getResourceType() { + return resourceType; + } + +} 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/core/src/com/cloud/storage/template/TemplateLocation.java b/core/src/com/cloud/storage/template/TemplateLocation.java index 58d023a4907..161a663981d 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; @@ -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 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"); + tmplInfo.installPath = _templatePath + _props.getProperty("filename"); // _templatePath endsWith / 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/core/src/com/cloud/agent/api/storage/DownloadCommand.java b/core/src/org/apache/cloudstack/storage/command/DownloadCommand.java similarity index 53% rename from core/src/com/cloud/agent/api/storage/DownloadCommand.java rename to core/src/org/apache/cloudstack/storage/command/DownloadCommand.java index c6ffe45a9ef..7e3d65c7bde 100644 --- a/core/src/com/cloud/agent/api/storage/DownloadCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/DownloadCommand.java @@ -14,89 +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; @@ -105,6 +43,8 @@ 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() { } @@ -120,40 +60,41 @@ 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(String secUrl, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) { - super(template.getUniqueName(), template.getUrl(), template.getFormat(), template.getAccountId()); + 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(); - this.setSecUrl(secUrl); + this.description = template.getDescription(); + if (_store instanceof NfsTO) { + this.setSecUrl(((NfsTO) _store).getUrl()); + } this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; } - public DownloadCommand(String secUrl, 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.maxDownloadSizeInBytes = maxDownloadSizeInBytes; - this.resourceType = ResourceType.VOLUME; - } - - public DownloadCommand(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.checksum = template.getChecksum(); - this.id = template.getId(); - this.description = template.getDisplayText(); - this.setSecUrl(secUrl); - 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.installPath = volume.getPath(); + this._store = volume.getDataStore(); + this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; + this.resourceType = ResourceType.VOLUME; + } + @Override + public long getId() { return id; } @@ -216,4 +157,28 @@ 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 String getInstallPath() { + return installPath; + } + + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + + + } diff --git a/core/src/com/cloud/agent/api/storage/DownloadProgressCommand.java b/core/src/org/apache/cloudstack/storage/command/DownloadProgressCommand.java similarity index 96% rename from core/src/com/cloud/agent/api/storage/DownloadProgressCommand.java rename to core/src/org/apache/cloudstack/storage/command/DownloadProgressCommand.java index 835847bedeb..72ca90172b1 100644 --- a/core/src/com/cloud/agent/api/storage/DownloadProgressCommand.java +++ b/core/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/core/test/com/cloud/agent/transport/RequestTest.java b/core/test/com/cloud/agent/transport/RequestTest.java index 64c1e0bddef..510be91ae6e 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; @@ -28,22 +30,25 @@ 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.storage.DownloadCommand; +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; 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 +56,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 +94,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; @@ -126,11 +131,46 @@ 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); + ListTemplateCommand cmd = new ListTemplateCommand(nfs); + 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); + assertEquals("nfs://192.168.56.10/opt/storage/secondary", ((NfsTO)((ListTemplateCommand)creq.getCommand()).getDataStore()).getUrl()); + } + 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, HypervisorType.KVM, null); - DownloadCommand cmd = new DownloadCommand("secUrl", 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"); @@ -161,7 +201,7 @@ public class RequestTest extends TestCase { } } } - + public void testLogging() { s_logger.info("Testing Logging"); GetHostStatsCommand cmd3 = new GetHostStatsCommand("hostguid", "hostname", 101); 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 44d53aaa175..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; }; @@ -159,11 +159,6 @@ public class BackupSnapshotCommandTest { "9012793e-0657-11e2-bebc-0050568b0057", "7167e0b2-f5b0-11e1-8414-0050568b0057", false, "vmName", 5); - @Test - public void testGetPrimaryStoragePoolNameLabel() { - String label = bsc.getPrimaryStoragePoolNameLabel(); - assertTrue(label.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e")); - } @Test public void testGetSecondaryStorageUrl() { @@ -199,37 +194,6 @@ public class BackupSnapshotCommandTest { assertEquals(expected, ssId); } - @Test - public void testGetPool() { - StorageFilerTO pool = bsc.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 testGetCreated() { 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 c2d69c0b0fd..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; }; @@ -142,12 +142,6 @@ public class SnapshotCommandTest { 102L, 103L); } - @Test - public void testGetPrimaryStoragePoolNameLabel() { - String label = ssc.getPrimaryStoragePoolNameLabel(); - assertTrue(label.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e")); - } - @Test public void testGetSecondaryStorageUrl() { String url = ssc.getSecondaryStorageUrl(); 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/developer/pom.xml b/developer/pom.xml index 9bfb79294fd..a680b8aa98e 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/docs/en-US/Release_Notes.xml b/docs/en-US/Release_Notes.xml index 8843f4c2e20..a4fcd471692 100644 --- a/docs/en-US/Release_Notes.xml +++ b/docs/en-US/Release_Notes.xml @@ -4641,11 +4641,6 @@ under the License. You'll be prompted for your password. # mysqldump -u root -p cloud > cloudstack-backup.sql - - Whether you're upgrading a Red Hat/CentOS based system or Ubuntu based system, - you're going to need to stop the CloudStack management server before proceeding. - # service cloud-management stop - If you have made changes to /etc/cloud/management/components.xml, you'll need to carry these @@ -5598,7 +5593,7 @@ service cloudstack-agent start $ sudo apt-get install cloudstack-management - You will need to manually install the cloudstack-agent + On KVM hosts, you will need to manually install the cloudstack-agent package: $ sudo apt-get install cloudstack-agent During the installation of cloudstack-agent, APT will copy @@ -5621,7 +5616,7 @@ service cloudstack-agent start service cloud-agent stop killall jsvc service cloudstack-agent start - + During the upgrade, log4j-cloud.xml was simply copied over, diff --git a/docs/en-US/about-password-encryption.xml b/docs/en-US/about-password-encryption.xml index 6c11c579ed2..a13ff60fc95 100644 --- a/docs/en-US/about-password-encryption.xml +++ b/docs/en-US/about-password-encryption.xml @@ -60,6 +60,6 @@ over a known port. The encryption type, database secret key, and Management Server secret key are set during &PRODUCT; installation. They are all parameters to the &PRODUCT; database setup script - (cloud-setup-databases). The default values are file, password, and password. It is, of course, + (cloudstack-setup-databases). The default values are file, password, and password. It is, of course, highly recommended that you change these to more secure keys. diff --git a/docs/en-US/add-gateway-vpc.xml b/docs/en-US/add-gateway-vpc.xml index a081faf7768..9a270f9d794 100644 --- a/docs/en-US/add-gateway-vpc.xml +++ b/docs/en-US/add-gateway-vpc.xml @@ -22,7 +22,8 @@ Adding a Private Gateway to a VPC A private gateway can be added by the root admin only. The VPC private network has 1:1 relationship with the NIC of the physical network. You can configure multiple private gateways - to a single VPC. No gateways with duplicated VLAN and IP are allowed in the same data center. + to a single VPC. No gateways with duplicated VLAN and IP are allowed in the same data + center. Log in to the &PRODUCT; UI as an administrator or end user. @@ -148,4 +149,18 @@ private gateway interface are blocked. You can change this default behaviour while creating a private gateway. +
+ Creating a Static Route + &PRODUCT; enables you to specify routing for the VPN connection you create. You can enter + one or CIDR addresses to indicate which traffic is to be routed back to the gateway. +
+
+ Blacklisting Routes + &PRODUCT; enables you to block a list of routes so that they are not assigned to any of + the VPC private gateways. Specify the list of routes that you want to blacklist in the + blacklisted.routes global parameter. Note that the parameter update affects + only new static route creations. If you block an existing static route, it remains intact and + continue functioning. You cannot add a static route if the route is blacklisted for the zone. + +
diff --git a/docs/en-US/building-devcloud.xml b/docs/en-US/building-devcloud.xml index 5f792c375a2..f3c4d19a5d9 100644 --- a/docs/en-US/building-devcloud.xml +++ b/docs/en-US/building-devcloud.xml @@ -27,6 +27,6 @@ The DevCloud appliance can be downloaded from the wiki at . It can also be built from scratch. Code is being developed to provide this alternative build. It is based on veewee, Vagrant and Puppet. The goal is to automate the DevCloud build and make this automation capability available to all within the source release of &PRODUCT; This is under heavy development. The code is located in the source tree under tools/devcloud - A preliminary wiki page describes the build at https://cwiki.pache.org/CLOUDSTACK/building-devcloud.html + A preliminary wiki page describes the build at https://cwiki.apache.org/confluence/display/CLOUDSTACK/Building+DevCloud diff --git a/docs/en-US/citrix-xenserver-installation.xml b/docs/en-US/citrix-xenserver-installation.xml index a5118d751d4..9ea632accca 100644 --- a/docs/en-US/citrix-xenserver-installation.xml +++ b/docs/en-US/citrix-xenserver-installation.xml @@ -103,7 +103,10 @@ >https://www.citrix.com/English/ss/downloads/, download the appropriate version of XenServer for your &PRODUCT; version (see ). Install it using the Citrix XenServer - Installation Guide. + Installation Guide. + Older Versions of XenServer + Note that you can download the most recent release of XenServer without having a Citrix account. If you wish to download older versions, you will need to create an account and look through the download archives. +
After installation, perform the following configuration steps, which are described in diff --git a/docs/en-US/database-replication.xml b/docs/en-US/database-replication.xml index bb144579ddf..8ca80713732 100644 --- a/docs/en-US/database-replication.xml +++ b/docs/en-US/database-replication.xml @@ -37,10 +37,14 @@ server_id=1 The server_id must be unique with respect to other servers. The recommended way to achieve this is to give the master an ID of 1 and each slave a sequential number greater than 1, so that the servers are numbered 1, 2, 3, etc. - Restart the MySQL service: + Restart the MySQL service. On RHEL/CentOS systems, use: # service mysqld restart + On Debian/Ubuntu systems, use: + +# service mysql restart + Create a replication account on the master and give it privileges. We will use the "cloud-repl" user with the password "password". This assumes that master and slave run on the 172.16.1.0/24 network. @@ -90,10 +94,14 @@ innodb_lock_wait_timeout=600 - Restart MySQL. + Restart MySQL. Use "mysqld" on RHEL/CentOS systems: # service mysqld restart + On Ubuntu/Debian systems use "mysql." + +# service mysql restart + Instruct the slave to connect to and replicate from the master. Replace the IP address, password, log file, and position with the values you have used in the previous steps. diff --git a/docs/en-US/management-server-install-client.xml b/docs/en-US/management-server-install-client.xml index b5329e3442a..47d6b3e1e72 100644 --- a/docs/en-US/management-server-install-client.xml +++ b/docs/en-US/management-server-install-client.xml @@ -32,11 +32,11 @@
Install on CentOS/RHEL We start by installing the required packages: - yum install cloud-client + yum install cloudstack-management
Install on Ubuntu - apt-get install cloud-client + apt-get install cloudstack-mangagement
diff --git a/docs/en-US/management-server-install-db-external.xml b/docs/en-US/management-server-install-db-external.xml index a28dee56934..29507209fbf 100644 --- a/docs/en-US/management-server-install-db-external.xml +++ b/docs/en-US/management-server-install-db-external.xml @@ -132,7 +132,7 @@ bind-address = 0.0.0.0 server node IP. If not specified, the local IP address will be used. - cloud-setup-databases cloud:<dbpassword>@<ip address mysql server> \ + cloudstack-setup-databases cloud:<dbpassword>@<ip address mysql server> \ --deploy-as=root:<password> \ -e <encryption_type> \ -m <management_server_key> \ diff --git a/docs/en-US/management-server-install-db-local.xml b/docs/en-US/management-server-install-db-local.xml index 310327fcc75..ff5ab60b91f 100644 --- a/docs/en-US/management-server-install-db-local.xml +++ b/docs/en-US/management-server-install-db-local.xml @@ -135,7 +135,7 @@ binlog-format = 'ROW' server node IP. If not specified, the local IP address will be used. - cloud-setup-databases cloud:<dbpassword>@localhost \ + cloudstack-setup-databases cloud:<dbpassword>@localhost \ --deploy-as=root:<password> \ -e <encryption_type> \ -m <management_server_key> \ @@ -160,7 +160,7 @@ binlog-format = 'ROW' Now that the database is set up, you can finish configuring the OS for the Management Server. This command will set up iptables, sudoers, and start the Management Server. - # cloud-setup-management + # cloudstack-setup-management You should see the message “&PRODUCT; Management Server setup is done.” diff --git a/docs/en-US/management-server-install-multi-node.xml b/docs/en-US/management-server-install-multi-node.xml index 21cf28fc719..ae925bf8447 100644 --- a/docs/en-US/management-server-install-multi-node.xml +++ b/docs/en-US/management-server-install-multi-node.xml @@ -53,12 +53,12 @@ linkend="sect-source-buildrpm"/> or as Configure the database client. Note the absence of the --deploy-as argument in this case. (For more details about the arguments to this command, see .) - # cloud-setup-databases cloud:dbpassword@dbhost -e encryption_type -m management_server_key -k database_key -i management_server_ip + # cloudstack-setup-databases cloud:dbpassword@dbhost -e encryption_type -m management_server_key -k database_key -i management_server_ip Configure the OS and start the Management Server: - # cloud-setup-management + # cloudstack-setup-management The Management Server on this node should now be running. diff --git a/docs/en-US/region-add.xml b/docs/en-US/region-add.xml index 960777c0a2e..802e462ce16 100644 --- a/docs/en-US/region-add.xml +++ b/docs/en-US/region-add.xml @@ -45,7 +45,7 @@ the additional command-line flag -r <region_id> to set a region ID for the new region. The default region is automatically assigned a region ID of 1, so your first additional region might be region 2. - cloud-setup-databases cloud:<dbpassword>@localhost --deploy-as=root:<password> -e <encryption_type> -m <management_server_key> -k <database_key> -r <region_id> + cloudstack-setup-databases cloud:<dbpassword>@localhost --deploy-as=root:<password> -e <encryption_type> -m <management_server_key> -k <database_key> -r <region_id> By the end of the installation procedure, the Management Server should have been started. Be sure that the Management Server installation was successful and complete. Add region 2 to region 1. Use the API command addRegion. (For information about how to make an API call, see the Developer's Guide.) @@ -82,7 +82,7 @@ However, you must repeat certain steps additional times for each additional region: Install &PRODUCT; in each additional region. Set the region ID for each region during the database setup step. - cloud-setup-databases cloud:<dbpassword>@localhost --deploy-as=root:<password> -e <encryption_type> -m <management_server_key> -k <database_key> -r <region_id> + cloudstack-setup-databases cloud:<dbpassword>@localhost --deploy-as=root:<password> -e <encryption_type> -m <management_server_key> -k <database_key> -r <region_id> Once the Management Server is running, add your new region to all existing regions by repeatedly calling the API command addRegion. For example, if you were adding region 3: @@ -125,4 +125,4 @@ http://<IP_of_region_3_Management_Server>:8080/client/api?command=addRegio http://<IP_of_region_2_Management_Server>:8080/client/api?command=removeRegion&id=3&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D
- \ No newline at end of file + diff --git a/docs/en-US/source-build.xml b/docs/en-US/source-build.xml index 8504385ee29..a56d304245f 100644 --- a/docs/en-US/source-build.xml +++ b/docs/en-US/source-build.xml @@ -28,8 +28,8 @@ Prior to the 4.0.0 incubating release, Ant was used to build &PRODUCT;. A migration to Maven started in the 4.0.0 cycle, and has completed in 4.1.0. The website and the wiki contain up to date information on the build procedure at: - https://cwiki.apache.org/CLOUDSTACK/building-with-maven.html - https://cwiki.apache.org/CLOUDSTACK/setting-up-cloudstack-development-environment.html + https://cwiki.apache.org/confluence/display/CLOUDSTACK/How+to+build+on+master+branch + https://cwiki.apache.org/confluence/display/CLOUDSTACK/Setting+up+CloudStack+Development+Environment The overarching steps to build &PRODUCT; are:. 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..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 @@ -18,19 +18,21 @@ */ 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) { + super(); this.clusterId = clusterId; this.podId = podId; this.zoneId = zoneId; } - + @Override public ScopeType getScopeType() { return this.type; @@ -40,11 +42,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 571a77c3786..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 @@ -18,22 +18,25 @@ */ 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 { 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 b6d5b689951..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 @@ -18,20 +18,30 @@ */ 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 { 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; + this.answer = answer; } - + 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/storage/src/org/apache/cloudstack/storage/motion/DataMotionService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java similarity index 65% 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 5ecbcb37afb..5e10a0ba7e7 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,22 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.motion; +package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.Map; -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.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; public interface DataMotionService { - public void copyAsync(DataObject srcData, DataObject destData, + void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); + + 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/storage/src/org/apache/cloudstack/storage/motion/DataMotionStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java similarity index 59% 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 e3859b4e131..6deb6c1afc0 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,25 +16,23 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.motion; +package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.Map; -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.VolumeInfo; 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); + boolean canHandle(DataObject srcData, DataObject destData); - public Void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback); - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, + boolean canHandle(Map volumeMap, Host srcHost, Host destHost); + + Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); + + 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 0827cf6b674..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 @@ -18,15 +18,34 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; +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(); - public String getUri(); - public DataStore getDataStore(); - public Long getSize(); - public DataObjectType getType(); - public DiskFormat getFormat(); - public String getUuid(); - public void processEvent(ObjectInDataStoreStateMachine.Event event); + long getId(); + + String getUri(); + + DataTO getTO(); + + DataStore getDataStore(); + + Long getSize(); + + DataObjectType getType(); + + String getUuid(); + + boolean delete(); + + void processEvent(ObjectInDataStoreStateMachine.Event event); + + 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 32ea996e638..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 @@ -20,8 +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); + String getInstallPath(); + + void setInstallPath(String path); + + long getObjectId(); + + long getDataStoreId(); + + 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 f101f243047..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 @@ -16,13 +16,27 @@ // 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(); + 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 cf5759b2924..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,17 +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; 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); + void createAsync(DataObject data, AsyncCompletionCallback callback); + + void deleteAsync(DataObject data, AsyncCompletionCallback callback); + + void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback); + + boolean canCopy(DataObject srcData, DataObject destData); + + void resize(DataObject data, AsyncCompletionCallback callback); + + DataTO getTO(DataObject data); + + 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 cb467093955..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 @@ -23,21 +23,18 @@ import java.util.Map; import com.cloud.agent.api.StoragePoolInfo; import com.cloud.hypervisor.Hypervisor.HypervisorType; - public interface DataStoreLifeCycle { - public DataStore initialize(Map dsInfos); + DataStore initialize(Map dsInfos); + + boolean attachCluster(DataStore store, ClusterScope scope); + + boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo); - public boolean attachCluster(DataStore store, ClusterScope scope); - public 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 15e49e133fb..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 @@ -21,11 +21,20 @@ 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); - public DataStore getPrimaryDataStore(long storeId); - public DataStore getDataStore(String uuid, DataStoreRole role); - public List getImageStores(Scope scope); - public DataStore registerDataStore(Map params, String providerUuid); + DataStore getDataStore(long storeId, DataStoreRole role); + + DataStore getPrimaryDataStore(long storeId); + + DataStore getDataStore(String uuid, DataStoreRole role); + + List getImageStoresByScope(ZoneScope scope); + + DataStore getImageStore(long zoneId); + + List getImageCacheStores(Scope scope); + + 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 115a52f92ac..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 @@ -21,17 +21,28 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.Map; import java.util.Set; - public interface DataStoreProvider { - public static enum DataStoreProviderType { - PRIMARY, - IMAGE + // constants for provider names + static final String NFS_IMAGE = "NFS"; + static final String S3_IMAGE = "S3"; + static final String SWIFT_IMAGE = "Swift"; + static final String SAMPLE_IMAGE = "Sample"; + + static final String DEFAULT_PRIMARY = "DefaultPrimary"; + + static enum DataStoreProviderType { + PRIMARY, IMAGE, ImageCache } - public DataStoreLifeCycle getDataStoreLifeCycle(); - public DataStoreDriver getDataStoreDriver(); - public HypervisorHostListener getHostListener(); - public String getName(); - public boolean configure(Map params); - public Set getTypes(); - + + DataStoreLifeCycle getDataStoreLifeCycle(); + + DataStoreDriver getDataStoreDriver(); + + HypervisorHostListener getHostListener(); + + String getName(); + + 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 906720a1f41..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,8 +24,11 @@ import com.cloud.storage.DataStoreProviderApiService; import com.cloud.utils.component.Manager; public interface DataStoreProviderManager extends Manager, DataStoreProviderApiService { - public DataStoreProvider getDataStoreProvider(String name); - public DataStoreProvider getDefaultPrimaryDataStoreProvider(); - public List getDataStoreProviders(); + DataStoreProvider getDataStoreProvider(String name); + DataStoreProvider getDefaultPrimaryDataStoreProvider(); + + 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 2ff45b1bf56..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,7 +22,13 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; public interface EndPoint { - public long getId(); - public Answer sendMessage(Command cmd); - public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); + long getId(); + + String getHostAddr(); + + String getPublicAddr(); + + Answer sendMessage(Command cmd); + + void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); } 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/EndPointSelector.java old mode 100755 new mode 100644 similarity index 77% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java index 65928bd5537..ca0cc2c970a --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java @@ -18,12 +18,14 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; -import java.net.URI; +import java.util.List; -import com.cloud.org.Grouping; +public interface EndPointSelector { + EndPoint select(DataObject srcData, DataObject destData); -public interface DataMigrationSubSystem { + EndPoint select(DataObject object); - Class getScopeCoverage(); - void migrate(URI source, URI dest, String reservationId); + EndPoint select(DataStore store); + + 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 c5e90ac894c..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 @@ -18,20 +18,30 @@ */ 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; - public HostScope(Long hostId) { + private Long zoneId; + + public HostScope(Long hostId, Long zoneId) { + super(); this.hostId = hostId; + this.zoneId = zoneId; } + @Override public ScopeType getScopeType() { - return this.type; + return ScopeType.HOST; } @Override public Long getScopeId() { return this.hostId; } + + public Long getZoneId() { + return zoneId; + } + } 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/ImageService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.java deleted file mode 100644 index 119f3b1d32f..00000000000 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.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.engine.subsystem.api.storage; - -import org.apache.cloudstack.framework.async.AsyncCallFuture; - -public interface ImageService { - 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); - -} 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/ImageStoreProvider.java similarity index 82% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java index ed4d42187be..0025ae1cde6 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/ImageStoreProvider.java @@ -18,17 +18,11 @@ */ 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; - } +import com.cloud.storage.ScopeType; + +public interface ImageStoreProvider extends DataStoreProvider { + + boolean isScopeSupported(ScopeType scope); + + boolean needDownloadSysTemplate(); } 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); + void takeSnapshot(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 3497f7a894f..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 @@ -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); + boolean isHypervisorSupported(HypervisorType hypervisor); - public String getUuid(); + boolean isLocalStorageSupported(); - public StoragePoolType getPoolType(); - public PrimaryDataStoreLifeCycle getLifeCycle(); + boolean isVolumeDiskTypeSupported(DiskFormat diskType); + + String getUuid(); + + StoragePoolType getPoolType(); + + 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 91d4734ef15..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 @@ -18,8 +18,12 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.storage.ScopeType; + public interface Scope { - public ScopeType getScopeType(); - public boolean isSameScope(Scope scope); - public Long getScopeId(); + ScopeType getScopeType(); + + boolean isSameScope(Scope scope); + + 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 1ff3ff25065..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 @@ -18,9 +18,12 @@ */ 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); + SnapshotInfo getSnapshot(long snapshotId, DataStore store); + + SnapshotInfo getSnapshot(DataObject obj, DataStore store); + + 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 b90404c5667..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 @@ -18,11 +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 SnapshotInfo getChild(); - public VolumeInfo getBaseVolume(); + SnapshotInfo getParent(); + + String getPath(); + + SnapshotInfo getChild(); + + VolumeInfo getBaseVolume(); + + void addPayload(Object data); + Long getDataCenterId(); - public Long getPrevSnapshotId(); + + 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 new file mode 100644 index 00000000000..80dbbf83590 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.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.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) { + 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/StorageSubSystem.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java similarity index 76% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java index 8043487d46b..d594a0728cb 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/SnapshotService.java @@ -14,16 +14,15 @@ // 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; +public interface SnapshotService { + SnapshotResult takeSnapshot(SnapshotInfo snapshot); -import com.cloud.org.Grouping; + SnapshotInfo backupSnapshot(SnapshotInfo snapshot); -public interface StorageSubSystem { - String getType(); - Class getScope(); + boolean deleteSnapshot(SnapshotInfo snapshot); - URI grantAccess(String vol, String reservationId); - URI RemoveAccess(String vol, String reservationId); + 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 e9492c4afc6..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 @@ -11,17 +11,19 @@ // 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.engine.subsystem.api.storage; +import com.cloud.storage.Snapshot; public interface SnapshotStrategy { - public boolean canHandle(SnapshotInfo snapshot); - public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId); - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); - public boolean deleteSnapshot(SnapshotInfo snapshot); - public boolean revertSnapshot(SnapshotInfo snapshot); + SnapshotInfo takeSnapshot(SnapshotInfo snapshot); + + SnapshotInfo backupSnapshot(SnapshotInfo snapshot); + + boolean deleteSnapshot(Long snapshotId); + + 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 new file mode 100644 index 00000000000..92724c91889 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.engine.subsystem.api.storage; + +public interface StorageCacheManager { + DataStore getCacheStorage(Scope scope); + + DataObject createCacheObject(DataObject data, Scope scope); + + /** + * only create cache object in db + * + * @param data + * @param scope + * @return + */ + 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/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 deleted file mode 100755 index fdb15c7331c..00000000000 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java +++ /dev/null @@ -1,68 +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 51714ec560b..01b5e788250 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 @@ -23,23 +23,28 @@ import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.storage.StoragePool; import com.cloud.utils.component.Adapter; import com.cloud.vm.DiskProfile; -import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; /** */ public interface StoragePoolAllocator extends Adapter { - /** - * Determines which storage pools are suitable for the guest virtual machine + /** + * Determines which storage pools are suitable for the guest virtual machine * - * @param DiskProfile dskCh - * @param VirtualMachineProfile vmProfile - * @param DeploymentPlan plan - * @param ExcludeList avoid + * @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); + * @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; + static int RETURN_UPTO_ALL = -1; } 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 80% 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..0b78da058ed 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 @@ -18,9 +18,14 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.storage.DataStoreRole; -public interface ImageDataFactory { +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/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 8e03503911e..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 @@ -18,5 +18,10 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; -public interface TemplateInfo extends DataObject { +import com.cloud.template.VirtualMachineTemplate; + +public interface TemplateInfo extends DataObject, VirtualMachineTemplate { + String getUniqueName(); + + 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 e05e7db67fa..00000000000 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java +++ /dev/null @@ -1,287 +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 new file mode 100644 index 00000000000..085fbbdb232 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.engine.subsystem.api.storage; + +import org.apache.cloudstack.framework.async.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; + +public interface TemplateService { + + class TemplateApiResult extends CommandResult { + private final TemplateInfo template; + + public TemplateApiResult(TemplateInfo template) { + super(); + this.template = template; + } + + public TemplateInfo getTemplate() { + return this.template; + } + } + + 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); + + AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore); + + 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 349325af45d..3b4aba970ba 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,13 +18,31 @@ */ 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; public interface VolumeInfo extends DataObject, Volume { - public boolean isAttachedVM(); - public void addPayload(Object data); - public Object getpayload(); - public HypervisorType getHypervisorType(); - public Long getLastPoolId(); + boolean isAttachedVM(); + + void addPayload(Object data); + + Object getpayload(); + + HypervisorType getHypervisorType(); + + Long getLastPoolId(); + + String getAttachedVmName(); + + void processEventOnly(ObjectInDataStoreStateMachine.Event event); + + void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer); + + boolean stateTransit(Volume.Event event); + + Long getBytesReadRate(); + Long getBytesWriteRate(); + Long getIopsReadRate(); + Long getIopsWriteRate(); } 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 3a1fe6ac226..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 @@ -19,20 +19,24 @@ 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; + import com.cloud.agent.api.to.VirtualMachineTO; 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) { + super(); this.volume = volume; } - + public VolumeInfo getVolume() { return this.volume; } @@ -57,27 +61,35 @@ public interface VolumeService { AsyncCallFuture expungeVolumeAsync(VolumeInfo volume); /** - * + * */ boolean cloneVolume(long volumeId, long baseVolId); /** - * + * */ - 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; AsyncCallFuture registerVolume(VolumeInfo volume, DataStore store); - + AsyncCallFuture resize(VolumeInfo volume); + void handleVolumeSync(DataStore store); + + 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 2d3d41f22b5..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 @@ -18,15 +18,17 @@ */ 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) { + super(); 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/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java similarity index 62% rename from engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java rename to engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java index a316223b24d..5a26d4a3f13 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java @@ -16,14 +16,32 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage; - -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +package org.apache.cloudstack.storage.command; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DiskTO; -public interface HostEndpointRpcServer { - void sendCommandAsync(HypervisorHostEndPoint ep, final Command command, final AsyncCompletionCallback callback); - Answer sendCommand(HypervisorHostEndPoint ep, final Command command); +public class AttachAnswer extends Answer { + private DiskTO disk; + + public AttachAnswer() { + super(null); + } + + public AttachAnswer(DiskTO disk) { + super(null); + 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/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java similarity index 61% rename from engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java index 1734bc409cc..6b4e9f7ed00 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java @@ -18,32 +18,38 @@ */ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.storage.to.ImageOnPrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.VolumeTO; - import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DiskTO; -public class CreateVolumeFromBaseImageCommand extends Command implements StorageSubSystemCommand { - private final VolumeTO volume; - private final ImageOnPrimaryDataStoreTO image; +public final class AttachCommand extends Command implements StorageSubSystemCommand { + private DiskTO disk; + private String vmName; - public CreateVolumeFromBaseImageCommand(VolumeTO volume, String image) { - this.volume = volume; - this.image = null; - } - - public VolumeTO getVolume() { - return this.volume; - } - - public ImageOnPrimaryDataStoreTO getImage() { - return this.image; + 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/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java similarity index 98% rename from engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java rename to engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java index cd15030084d..6d5bbaf6a68 100644 --- a/engine/storage/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/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java similarity index 89% rename from engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java rename to engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java index 8aaca94aee0..2083876b567 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java @@ -20,19 +20,20 @@ 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/engine/subsystem/api/storage/CommandResult.java b/engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java similarity index 94% 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 cc45914dc41..0a33c519f01 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,32 +16,33 @@ * 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; 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/storage/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java similarity index 75% rename from engine/storage/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java rename to engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java index 53e082e6950..95c0e8990f8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java @@ -17,17 +17,21 @@ package org.apache.cloudstack.storage.command; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataTO; public class CopyCmdAnswer extends Answer { - private final String path; - - public CopyCmdAnswer(Command cmd, String path) { - super(cmd); - this.path = path; + private DataTO newData; + + 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/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java similarity index 60% rename from engine/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java rename to engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java index 10478ef24c7..852d8013c93 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -17,29 +17,39 @@ package org.apache.cloudstack.storage.command; import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataTO; -public class CopyCmd extends Command implements StorageSubSystemCommand { - private String srcUri; - private String destUri; +public final class CopyCommand extends Command implements StorageSubSystemCommand { + private DataTO srcTO; + private DataTO destTO; + private DataTO cacheTO; - public CopyCmd(String srcUri, String destUri) { + public CopyCommand(DataTO srcData, DataTO destData, int timeout) { super(); - this.srcUri = srcUri; - this.destUri = destUri; + this.srcTO = srcData; + this.destTO = destData; + this.setWait(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; + } + + public DataTO getCacheTO() { + return cacheTO; + } + + public void setCacheTO(DataTO cacheTO) { + this.cacheTO = cacheTO; } } 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 65% rename from engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java rename to engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java index 43540de2bd3..b0c47447f6f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java @@ -19,30 +19,25 @@ package org.apache.cloudstack.storage.command; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataTO; + +public final class CreateObjectAnswer extends Answer { + private DataTO data; -public class CreateObjectAnswer extends Answer { - private String path; - private Long size; protected CreateObjectAnswer() { super(); } - public CreateObjectAnswer(Command cmd, String path, Long size) { - super(cmd); - this.path = path; - this.size = size; - } - - public CreateObjectAnswer(Command cmd, boolean status, String result) { - super(cmd, status, result); + public CreateObjectAnswer(DataTO data) { + super(); + this.data = data; } - public String getPath() { - return this.path; + public DataTO getData() { + return this.data; } - - public Long getSize() { - return this.size; + + public CreateObjectAnswer(String errMsg) { + super(null, false, errMsg); } } 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 77% rename from engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java index 86d3bd42410..121a7ee449c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java @@ -19,13 +19,14 @@ 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 { - protected String objectUri; +public final class CreateObjectCommand extends Command implements StorageSubSystemCommand { + private DataTO data; - public CreateObjectCommand(String objectUri) { + public CreateObjectCommand(DataTO obj) { super(); - this.objectUri = objectUri; + this.data = obj; } protected CreateObjectCommand() { @@ -34,12 +35,11 @@ public class CreateObjectCommand extends Command implements StorageSubSystemComm @Override public boolean executeInSequence() { - // TODO Auto-generated method stub return false; } - - public String getObjectUri() { - return this.objectUri; + + public DataTO getData() { + return this.data; } } 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 88% rename from engine/storage/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java rename to engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java index 0e50950843e..b536028927f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java @@ -18,19 +18,20 @@ 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/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java similarity index 75% rename from engine/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java index 5d948d19356..76696da30ae 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java @@ -18,27 +18,28 @@ */ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.storage.to.VolumeTO; - import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataTO; -public class DeleteCommand extends Command implements StorageSubSystemCommand { - private String uri; - public DeleteCommand(String uri) { - this.uri = uri; +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 String getUri() { - return this.uri; + + public DataTO getData() { + return this.data; } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManager.java b/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java similarity index 59% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManager.java rename to engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java index e1fd46b76df..62ce2465ab5 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManager.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java @@ -16,15 +16,32 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.manager; +package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DiskTO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.utils.fsm.StateMachine2; +public final class DettachAnswer extends Answer { + private DiskTO disk; -public interface ImageDataManager { - StateMachine2 getStateMachine(); + public DettachAnswer() { + super(null); + } + public DettachAnswer(DiskTO disk) { + super(null); + 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/storage/src/org/apache/cloudstack/storage/image/db/ImageDaoStoreDaoImpl.java b/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java similarity index 53% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDaoStoreDaoImpl.java rename to engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java index 3f3e9ca95fb..a0ab4b2e6f4 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDaoStoreDaoImpl.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java @@ -16,23 +16,40 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.db; +package org.apache.cloudstack.storage.command; -import org.springframework.stereotype.Component; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DiskTO; -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; +public class DettachCommand extends Command implements StorageSubSystemCommand { + private DiskTO disk; + private String vmName; -@Component -public class ImageDaoStoreDaoImpl extends GenericDaoBase implements ImageDataStoreDao { + public DettachCommand(DiskTO disk, String vmName) { + super(); + this.disk = disk; + this.vmName = vmName; + } @Override - public ImageDataStoreVO findByName(String name) { - SearchCriteriaService sc = SearchCriteria2.create(ImageDataStoreVO.class); - sc.addAnd(sc.getEntity().getName(), Op.EQ, name); - return sc.find(); + public boolean executeInSequence() { + 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 new file mode 100644 index 00000000000..9528ff788d8 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/command/DownloadSystemTemplateCommand.java @@ -0,0 +1,129 @@ +// 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.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 Long resourceId; + private Long accountId; + private String url; + private Long maxDownloadSizeInBytes; + private String name; + + protected DownloadSystemTemplateCommand() { + super(); + } + + 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(); + 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 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; + } + + 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/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/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/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java similarity index 67% rename from engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index dca83ce0b8a..70e9bb386e0 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -18,8 +18,20 @@ */ 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 DataStoreProviderDao extends GenericDao { - public DataStoreProviderVO findByName(String name); +public interface ImageStoreDao extends GenericDao { + ImageStoreVO findByName(String name); + + List findByProvider(String provider); + + List findByScope(ZoneScope scope); + + List findImageCacheByScope(ZoneScope scope); + + 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 new file mode 100644 index 00000000000..b9221489e05 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java @@ -0,0 +1,82 @@ +// 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_store_details") +public class ImageStoreDetailVO 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 ImageStoreDetailVO() { + } + + public ImageStoreDetailVO(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; + } + +} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java similarity index 69% rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java index b248758bc12..91fff280d91 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java @@ -14,3 +14,17 @@ // 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 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/ImageDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java similarity index 53% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java index 4cb402a1271..5ed48a3781c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java @@ -16,7 +16,9 @@ * 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; import javax.persistence.Column; import javax.persistence.Entity; @@ -26,36 +28,69 @@ 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.DataStoreRole; +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 { +@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; @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; - + private Long dcId; + @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; + + @Column(name = "role") + @Enumerated(value = EnumType.STRING) + private DataStoreRole role; + + @Column(name = "parent") + private String parent; + + @Column(name = "total_size") + private Long totalSize; + + @Column(name = "used_bytes") + private Long usedBytes; + + public DataStoreRole getRole() { + return role; + } + + public void setRole(DataStoreRole role) { + this.role = role; + } + public long getId() { return this.id; } @@ -75,36 +110,84 @@ 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 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; + } + + 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 String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public Long getTotalSize() { + return totalSize; + } + + public void setTotalSize(Long totalSize) { + 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/PrimaryDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java index d436762c25a..99b7b9c92b4 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 @@ -16,100 +16,110 @@ // under the License. package org.apache.cloudstack.storage.datastore.db; -import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; - import com.cloud.hypervisor.Hypervisor.HypervisorType; +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); List findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType); } 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 d461d58ddfc..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 @@ -28,12 +28,12 @@ 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.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePoolStatus; import com.cloud.utils.db.DB; @@ -49,141 +49,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.setUsedBytes(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 @@ -194,238 +189,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 new file mode 100644 index 00000000000..01f02208307 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -0,0 +1,40 @@ +// 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.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 { + + List listByStoreId(long id, DataStoreRole role); + + void deletePrimaryRecordsForStore(long id); + + SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId); + + SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role); + + 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 new file mode 100644 index 00000000000..2ae3e8cdbda --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -0,0 +1,260 @@ +// 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.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 org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; + +import com.cloud.storage.DataStoreRole; +import com.cloud.utils.db.GenericDao; +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 = "store_role") + @Enumerated(EnumType.STRING) + private DataStoreRole role; + + @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 = "parent_snapshot_id") + private long parentSnapshotId; + + @Column(name = "job_id") + private String jobId; + + @Column(name = "install_path") + private String installPath; + + @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; + + @Column(name = "ref_cnt") + Long refCnt; + + public String getInstallPath() { + return installPath; + } + + @Override + public long getDataStoreId() { + return dataStoreId; + } + + public void setDataStoreId(long storeId) { + this.dataStoreId = storeId; + } + + 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; + } + + public 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 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; + } + + public void setState(ObjectInDataStoreStateMachine.State state) { + this.state = state; + } + + @Override + public long getObjectId() { + return this.getSnapshotId(); + } + + public DataStoreRole getRole() { + return role; + } + + public void setRole(DataStoreRole role) { + this.role = role; + } + + @Override + public State getObjectInStoreState() { + return this.state; + } + + public long getParentSnapshotId() { + return parentSnapshotId; + } + + public void setParentSnapshotId(long parentSnapshotId) { + this.parentSnapshotId = parentSnapshotId; + } + + public Long getRefCnt() { + return refCnt; + } + + public void incrRefCnt() { + this.refCnt++; + } + + public void decrRefCnt() { + this.refCnt--; + } +} diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java index 699beef90c2..e51f3a38996 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java @@ -26,28 +26,28 @@ import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="storage_pool_details") +@Table(name = "storage_pool_details") public class StoragePoolDetailVO implements InternalIdentity { @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 StoragePoolDetailVO(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/StoragePoolDetailsDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java index 237f235704d..49f4f196245 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java @@ -18,12 +18,13 @@ package org.apache.cloudstack.storage.datastore.db; import java.util.Map; - import com.cloud.utils.db.GenericDao; public interface StoragePoolDetailsDao extends GenericDao { - + 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 0262f65af0a..9b8de679b08 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,19 +29,19 @@ import javax.persistence.TableGenerator; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; - import com.cloud.hypervisor.Hypervisor.HypervisorType; 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; @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; @@ -71,8 +71,8 @@ public class StoragePoolVO implements StoragePool{ @Column(name = "pod_id", updatable = true) private Long podId; - @Column(name = "available_bytes", updatable = true, nullable = true) - private long availableBytes; + @Column(name = "used_bytes", updatable = true, nullable = true) + private long usedBytes; @Column(name = "capacity_bytes", updatable = true, nullable = true) private long capacityBytes; @@ -118,15 +118,15 @@ 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; this.dataCenterId = dataCenterId; - this.availableBytes = availableBytes; + this.usedBytes = availableBytes; this.capacityBytes = capacityBytes; this.hostAddress = hostAddress; this.path = hostPath; @@ -136,7 +136,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.usedBytes, + that.capacityBytes, that.hostAddress, that.port, that.path); } public StoragePoolVO(StoragePoolType type, String hostAddress, int port, String path) { @@ -148,7 +149,6 @@ public class StoragePoolVO implements StoragePool{ this.uuid = UUID.randomUUID().toString(); } - public String getName() { return name; } @@ -181,8 +181,8 @@ public class StoragePoolVO implements StoragePool{ return dataCenterId; } - public long getAvailableBytes() { - return availableBytes; + public long getUsedBytes() { + return usedBytes; } public String getStorageProviderName() { @@ -197,8 +197,8 @@ public class StoragePoolVO implements StoragePool{ return capacityBytes; } - public void setAvailableBytes(long available) { - availableBytes = available; + public void setUsedBytes(long available) { + usedBytes = available; } public void setCapacityBytes(long capacity) { @@ -307,11 +307,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 new file mode 100644 index 00000000000..13b84ff3dba --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -0,0 +1,63 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.storage.datastore.db; + +import java.util.List; + +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +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 { + + List listByStoreId(long id); + + List listDestroyed(long storeId); + + void deletePrimaryRecordsForStore(long id); + + void deletePrimaryRecordsForTemplate(long templateId); + + List listByTemplateStore(long templateId, long storeId); + + List listByTemplateStoreStatus(long templateId, long storeId, State... states); + + 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); + + TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId, boolean lock); + + TemplateDataStoreVO findByTemplate(long templateId, DataStoreRole role); + + TemplateDataStoreVO findByTemplateZone(long templateId, Long zoneId, DataStoreRole role); + + List 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 new file mode 100755 index 00000000000..c6b434dbc1a --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -0,0 +1,372 @@ +// 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.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 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; +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; // this can be null for baremetal templates + + @Column(name = "template_id") + private long templateId; + + @Column(name = "store_role") + @Enumerated(EnumType.STRING) + private DataStoreRole dataStoreRole; + + @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; + + @Column(name = "ref_cnt") + Long refCnt; + + public TemplateDataStoreVO(Long hostId, long templateId) { + super(); + this.dataStoreId = hostId; + this.templateId = templateId; + this.state = ObjectInDataStoreStateMachine.State.Allocated; + this.refCnt = 0L; + } + + 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.refCnt = 0L; + this.installPath = installPath; + this.setDownloadUrl(downloadUrl); + switch (downloadState) { + case DOWNLOADED: + this.state = ObjectInDataStoreStateMachine.State.Ready; + break; + case CREATING: + case DOWNLOAD_IN_PROGRESS: + case UPLOAD_IN_PROGRESS: + this.state = ObjectInDataStoreStateMachine.State.Creating2; + break; + case DOWNLOAD_ERROR: + case UPLOAD_ERROR: + this.state = ObjectInDataStoreStateMachine.State.Failed; + break; + case ABANDONED: + this.state = ObjectInDataStoreStateMachine.State.Destroyed; + break; + default: + this.state = ObjectInDataStoreStateMachine.State.Allocated; + break; + } + } + + public TemplateDataStoreVO() { + this.refCnt = 0L; + } + + @Override + public String getInstallPath() { + return installPath; + } + + @Override + public long getDataStoreId() { + return dataStoreId; + } + + public void setDataStoreId(long storeId) { + this.dataStoreId = storeId; + } + + 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; + } + + @Override + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public Status getDownloadState() { + return downloadState; + } + + 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 void setState(ObjectInDataStoreStateMachine.State state) { + this.state = state; + } + + public long getUpdatedCount() { + return this.updatedCount; + } + + public void incrUpdatedCount() { + this.updatedCount++; + } + + public void decrUpdatedCount() { + this.updatedCount--; + } + + public Date getUpdated() { + return updated; + } + + @Override + public long getObjectId() { + return this.getTemplateId(); + } + + @Override + public State getObjectInStoreState() { + return this.state; + } + + public DataStoreRole getDataStoreRole() { + return dataStoreRole; + } + + public void setDataStoreRole(DataStoreRole dataStoreRole) { + this.dataStoreRole = dataStoreRole; + } + + public Long getRefCnt() { + return refCnt; + } + + public void incrRefCnt() { + this.refCnt++; + } + + public void decrRefCnt() { + this.refCnt--; + } + +} diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java new file mode 100644 index 00000000000..4152516bcf0 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java @@ -0,0 +1,41 @@ +// 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.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 VolumeDataStoreDao extends GenericDao, + StateDao { + + List listByStoreId(long id); + + void deletePrimaryRecordsForStore(long id); + + VolumeDataStoreVO findByVolume(long volumeId); + + VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId); + + VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId, boolean lock); + + 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 new file mode 100755 index 00000000000..222447fa4a5 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/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.datastore.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 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.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 = "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; + + @Column(name = "ref_cnt") + Long refCnt; + + public String getInstallPath() { + return installPath; + } + + @Override + public long getDataStoreId() { + return dataStoreId; + } + + public void setDataStoreId(long storeId) { + this.dataStoreId = storeId; + } + + 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; + this.refCnt = 0L; + } + + public VolumeDataStoreVO(long hostId, long volumeId, Date lastUpdated, int downloadPercent, Status downloadState, + String localDownloadPath, String errorString, String jobId, String installPath, String downloadUrl, + String checksum) { + // 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.refCnt = 0L; + } + + public VolumeDataStoreVO() { + this.refCnt = 0L; + } + + 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 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; + } + + public void setState(ObjectInDataStoreStateMachine.State state) { + this.state = state; + } + + @Override + public long getObjectId() { + return this.getVolumeId(); + } + + @Override + public State getObjectInStoreState() { + return this.state; + } + + public Long getRefCnt() { + return refCnt; + } + + public void incrRefCnt() { + this.refCnt++; + } + + public void decrRefCnt() { + this.refCnt--; + } + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java similarity index 81% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java rename to engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java index ed2274e3d40..90deff96c92 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java +++ b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java @@ -26,10 +26,21 @@ 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.ImageStore; +import com.cloud.storage.Storage.ImageFormat; + +public interface ImageStoreEntity extends DataStore, ImageStore { TemplateInfo getTemplate(long templateId); + VolumeInfo getVolume(long volumeId); + SnapshotInfo getSnapshot(long snapshotId); + boolean exists(DataObject object); + 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/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreInfo.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java similarity index 88% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreInfo.java rename to engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java index b6b9a2a55d7..7261a15a486 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreInfo.java +++ b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java @@ -20,7 +20,8 @@ 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 String getType(); +public interface ImageStoreInfo extends DataStore { + long getImageStoreId(); + + 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 new file mode 100644 index 00000000000..0037ea57242 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java @@ -0,0 +1,79 @@ +// 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.image.datastore.ImageStoreInfo; + +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.storage.DataStoreRole; + +public class ImageStoreTO implements DataStoreTO { + 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 getProtocol() { + return this.type; + } + + public String getUri() { + return this.uri; + } + + public String getProviderName() { + 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; + } + + @Override + public String toString() { + return new StringBuilder("ImageStoreTO[type=").append(type).append("|provider=").append(providerName) + .append("|role=").append(role).append("|uri=").append(uri).append("]").toString(); + } +} 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 50% rename from engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java rename to engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java index aa47e8f4977..5e870df3716 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java @@ -18,31 +18,86 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; -public class PrimaryDataStoreTO { +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 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; } + + @Override + 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; + } + + @Override + public String toString() { + return new StringBuilder("PrimaryDataStoreTO[uuid=").append(uuid).append("|name=").append(name) + .append("|id=").append(id).append("|pooltype=").append(poolType).append("]").toString(); + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java new file mode 100644 index 00000000000..1115aece6ff --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java @@ -0,0 +1,126 @@ +// 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; + +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 { + 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; + } + + @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; + } + + 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; + } + + @Override + 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; + } + + public HypervisorType getHypervisorType() { + return hypervisorType; + } + + public void setHypervisorType(HypervisorType hypervisorType) { + this.hypervisorType = hypervisorType; + } + + @Override + public String toString() { + return new StringBuilder("SnapshotTO[datastore=").append(dataStore).append("|volume=").append(volume).append("|path") + .append(path).append("]").toString(); + } +} diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java new file mode 100644 index 00000000000..abe59eb2b4d --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -0,0 +1,199 @@ +// 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.TemplateInfo; + +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; + +public class TemplateObjectTO implements DataTO { + private String path; + private String origUrl; + 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 String guestOsType; + private Long size; + + 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.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(); + if (template.getDataStore() != null) { + this.imageDataStore = template.getDataStore().getTO(); + } + } + + @Override + public String getPath() { + return this.path; + } + + public String getUuid() { + return this.uuid; + } + + @Override + public long getId() { + return id; + } + + public void setId(long id){ + this.id = 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; + } + + + @Override + public DataObjectType getObjectType() { + return DataObjectType.TEMPLATE; + } + + @Override + public DataStoreTO getDataStore() { + return this.imageDataStore; + } + + public void setDataStore(DataStoreTO store){ + this.imageDataStore = store; + } + + /** + * @return the name + */ + 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 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; + } + + public String getGuestOsType() { + return guestOsType; + } + + public void setGuestOsType(String guestOsType) { + this.guestOsType = guestOsType; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + @Override + public String toString() { + return new StringBuilder("TemplateTO[id=").append(id).append("|origUrl=").append(origUrl) + .append("|name").append(name).append("]").toString(); + } +} diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java new file mode 100644 index 00000000000..ab3d5ea14d3 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -0,0 +1,215 @@ +// 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.VolumeInfo; + +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; +import com.cloud.storage.Volume; + +public class VolumeObjectTO implements DataTO { + private String uuid; + private Volume.Type volumeType; + private DataStoreTO dataStore; + private String name; + private long size; + private String path; + private Long volumeId; + private String vmName; + private long accountId; + private String chainInfo; + private Storage.ImageFormat format; + private long id; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; + + public VolumeObjectTO() { + + } + + public VolumeObjectTO(VolumeInfo volume) { + this.uuid = volume.getUuid(); + this.path = volume.getPath(); + this.accountId = volume.getAccountId(); + if (volume.getDataStore() != null) { + this.dataStore = volume.getDataStore().getTO(); + } else { + this.dataStore = null; + } + this.vmName = volume.getAttachedVmName(); + this.size = volume.getSize(); + this.setVolumeId(volume.getId()); + this.chainInfo = volume.getChainInfo(); + this.volumeType = volume.getVolumeType(); + this.name = volume.getName(); + this.setId(volume.getId()); + this.format = volume.getFormat(); + this.bytesReadRate = volume.getBytesReadRate(); + this.bytesWriteRate = volume.getBytesWriteRate(); + this.iopsReadRate = volume.getIopsReadRate(); + this.iopsWriteRate = volume.getIopsWriteRate(); + } + + public String getUuid() { + return this.uuid; + } + + @Override + public String getPath() { + return this.path; + } + + public Volume.Type getVolumeType() { + return this.volumeType; + } + + @Override + public DataStoreTO getDataStore() { + return this.dataStore; + } + + + public void setDataStore(DataStoreTO store){ + this.dataStore = store; + } + + public void setDataStore(PrimaryDataStoreTO dataStore) { + this.dataStore = dataStore; + } + + public String getName() { + return this.name; + } + + public long getSize() { + return this.size; + } + + @Override + 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; + } + + public Long getVolumeId() { + return volumeId; + } + + public void setVolumeId(Long volumeId) { + this.volumeId = volumeId; + } + + public long getAccountId() { + return accountId; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + public String getVmName() { + return vmName; + } + + public void setVmName(String vmName) { + this.vmName = vmName; + } + + public String getChainInfo() { + return chainInfo; + } + + public void setChainInfo(String chainInfo) { + this.chainInfo = chainInfo; + } + + @Override + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Storage.ImageFormat getFormat() { + return format; + } + + public void setFormat(Storage.ImageFormat format) { + this.format = format; + } + + @Override + public String toString() { + return new StringBuilder("volumeTO[uuid=").append(uuid).append("|path=").append(path) + .append("|datastore=").append(dataStore).append("]").toString(); + } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + +} 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/components-api/src/com/cloud/agent/AgentManager.java b/engine/components-api/src/com/cloud/agent/AgentManager.java index 306a40f31a2..5b12ff1f965 100755 --- a/engine/components-api/src/com/cloud/agent/AgentManager.java +++ b/engine/components-api/src/com/cloud/agent/AgentManager.java @@ -131,10 +131,7 @@ 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/engine/components-api/src/com/cloud/agent/Listener.java b/engine/components-api/src/com/cloud/agent/Listener.java index 47b9bc3011d..242f90cfeed 100755 --- a/engine/components-api/src/com/cloud/agent/Listener.java +++ b/engine/components-api/src/com/cloud/agent/Listener.java @@ -22,39 +22,39 @@ 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; /** * There are several types of events that the AgentManager forwards - * + * * 1. Agent Connect & Disconnect * 2. Commands sent by the agent. * 3. Answers sent by the agent. */ public interface Listener { - /** - * - * @param agentId id of the agent - * @param seq sequence number return by the send() method. - * @param answers answers to the commands. - * @return true if processed. false if not. - */ + /** + * + * @param agentId id of the agent + * @param seq sequence number return by the send() method. + * @param answers answers to the commands. + * @return true if processed. false if not. + */ boolean processAnswers(long agentId, long seq, Answer[] answers); /** * This method is called by the AgentManager when an agent sent * a command to the server. In order to process these commands, * the Listener must be registered for host commands. - * + * * @param agentId id of the agent. * @param seq sequence number of the command sent. * @param commands commands that were sent. * @return true if you processed the commands. false if not. */ boolean processCommands(long agentId, long seq, Command[] commands); - + /** * process control command sent from agent under its management * @param agentId @@ -72,26 +72,26 @@ 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 * from this server if the listener has been registered for host events. - * + * * If the Listener is passed to the send() method, this method is * also called by AgentManager if the agent disconnected. - * + * * @param agentId id of the agent * @param state the current state of the agent. */ boolean processDisconnect(long agentId, Status state); - + /** * If this Listener is passed to the send() method, this method * is called by AgentManager after processing an answer * from the agent. Returning true means you're expecting more * answers from the agent using the same sequence number. - * + * * @return true if expecting more answers using the same sequence number. */ boolean isRecurring(); @@ -102,7 +102,7 @@ public interface Listener { * is in seconds. -1 indicates to wait forever. 0 indicates to * use the default timeout. If the timeout is * reached, processTimeout on this same Listener is called. - * + * * @return timeout in seconds before processTimeout is called. */ int getTimeout(); @@ -115,5 +115,5 @@ public interface Listener { * @return true if processed; false if not. */ boolean processTimeout(long agentId, long seq); - + } diff --git a/engine/components-api/src/com/cloud/network/NetworkManager.java b/engine/components-api/src/com/cloud/network/NetworkManager.java index 0054c9af7e5..3e73a8cea6c 100755 --- a/engine/components-api/src/com/cloud/network/NetworkManager.java +++ b/engine/components-api/src/com/cloud/network/NetworkManager.java @@ -385,4 +385,5 @@ public interface NetworkManager { DhcpServiceProvider getDhcpServiceProvider(Network network); PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException; + } diff --git a/engine/components-api/src/com/cloud/storage/VolumeManager.java b/engine/components-api/src/com/cloud/storage/VolumeManager.java index 5345aa73e12..15f24f78b9a 100644 --- a/engine/components-api/src/com/cloud/storage/VolumeManager.java +++ b/engine/components-api/src/com/cloud/storage/VolumeManager.java @@ -113,6 +113,7 @@ public interface VolumeManager extends VolumeApiService { DiskOfferingVO offering, VMTemplateVO template, VMInstanceVO vm, Account owner); + String getVmNameFromVolumeId(long volumeId); String getStoragePoolOfVolume(long volumeId); diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 97a399065ba..f378f4fd965 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -921,7 +921,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VirtualMachineTO vmTO = hvGuru.implement(vmProfile); cmds = new Commands(OnError.Stop); - cmds.addCommand(new StartCommand(vmTO, dest.getHost())); + cmds.addCommand(new StartCommand(vmTO, dest.getHost(), true)); vmGuru.finalizeDeployment(cmds, vmProfile, dest, reservation); @@ -957,7 +957,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.info("The guru did not like the answers so stopping " + vm); } - StopCommand cmd = new StopCommand(vm); + StopCommand cmd = new StopCommand(vm, true); StopAnswer answer = (StopAnswer) _agentMgr.easySend(destHostId, cmd); if (answer == null || !answer.getResult()) { s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers")); @@ -1045,7 +1045,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected boolean sendStop(VirtualMachineGuru guru, VirtualMachineProfile profile, boolean force) { VirtualMachine vm = profile.getVirtualMachine(); - StopCommand stop = new StopCommand(vm); + StopCommand stop = new StopCommand(vm, true); try { Answer answer = _agentMgr.send(vm.getHostId(), stop); if (!answer.getResult()) { @@ -1248,7 +1248,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac vmGuru.prepareStop(profile); - StopCommand stop = new StopCommand(vm); + StopCommand stop = new StopCommand(vm, true); boolean stopped = false; StopAnswer answer = null; try { @@ -2056,11 +2056,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } public Command cleanup(VirtualMachine vm) { - return new StopCommand(vm); + return new StopCommand(vm, true); } public Command cleanup(String vmName) { - return new StopCommand(vmName); + return new StopCommand(vmName, true); } /* public Commands fullHostSync(final long hostId, StartupRoutingCommand startup) { @@ -2702,7 +2702,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; } diff --git a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java index 192f99a5d14..ae9aab758c2 100644 --- a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -97,6 +97,7 @@ import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.snapshot.VMSnapshotManager; @@ -151,6 +152,8 @@ public class VirtualMachineManagerImplTest { ConfigDepot _configDepot; @Mock HostVO hostVO; + @Mock + UserVmDetailVO _vmDetailVO; @Mock EntityManager _entityMgr; @@ -160,6 +163,7 @@ public class VirtualMachineManagerImplTest { @Mock DataCenterDao _dcDao; @Mock DiskOfferingDao _diskOfferingDao; @Mock PrimaryDataStoreDao _storagePoolDao; + @Mock UserVmDetailsDao _vmDetailsDao; @Mock StoragePoolHostDao _poolHostDao; @Mock NetworkManager _networkMgr; @Mock HypervisorGuruManager _hvGuruMgr; @@ -231,14 +235,24 @@ public class VirtualMachineManagerImplTest { DeployDestination dest = new DeployDestination(null, null, null, _host); long l = 1L; + when(_vmInstance.getId()).thenReturn(3L); + when(_vmDetailsDao.findDetail(3L, VirtualMachine.IsDynamicScalingEnabled)).thenReturn(_vmDetailVO); + when(_vmDetailVO.getValue()).thenReturn("true"); when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance); ServiceOfferingVO newServiceOffering = getSvcoffering(512); when(_hostDao.findById(_vmInstance.hostId)).thenReturn(hostVO); when(hostVO.getClusterId()).thenReturn(1L); // when(_configDepot.getConfigValue(Config.MemOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), 1L)).thenReturn("1.0"); +// when(_configServer.getConfigValue(Config.CPUOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), 1L)).thenReturn("1.0"); + when(_vmInstance.getHostId()).thenReturn(1L); + when(_hostDao.findById(1L)).thenReturn(hostVO); + when(_vmInstance.getDataCenterId()).thenReturn(1L); + when(hostVO.getClusterId()).thenReturn(1L); +// when(_configServer.getConfigValue(Config.EnableDynamicallyScaleVm.key(), Config.ConfigurationParameterScope.zone.toString(), 1L)).thenReturn("true"); +// when(_configServer.getConfigValue(Config.MemOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), 1L)).thenReturn("1.0"); // when(_configServer.getConfigValue(Config.CPUOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), 1L)).thenReturn("1.0"); ScaleVmCommand reconfigureCmd = new ScaleVmCommand("myVmName", newServiceOffering.getCpu(), - newServiceOffering.getSpeed(), newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse()); + newServiceOffering.getSpeed(), newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse(), true); Answer answer = new ScaleVmAnswer(reconfigureCmd, true, "details"); when(_agentMgr.send(2l, reconfigureCmd)).thenReturn(null); _vmMgr.reConfigureVm(_vmInstance, getSvcoffering(256), false); diff --git a/engine/pom.xml b/engine/pom.xml index 169425ae14e..3d305bc5c40 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -37,13 +37,25 @@ storage storage/volume storage/image - storage/imagemotion - storage/backup + storage/datamotion + storage/cache storage/snapshot - storage/integration-test components-api schema network service + + + integration-test + + + nonoss + + + + storage/integration-test + + + diff --git a/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java b/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java index 9f73029349f..a51c3643353 100644 --- a/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java +++ b/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java @@ -223,6 +223,13 @@ public class FirewallRuleVO implements FirewallRule { } + public FirewallRuleVO(String xId, Long ipAddressId, Integer portStart, Integer portEnd, String protocol, + long networkId, long accountId, long domainId, Purpose purpose, List sourceCidrs, Integer icmpCode, + Integer icmpType, Long related, TrafficType trafficType, FirewallRuleType type) { + this(xId, ipAddressId, portStart, portEnd, protocol, networkId, accountId, domainId, purpose, sourceCidrs, icmpCode, icmpType, related, trafficType); + this.type = type; + } + public FirewallRuleVO(String xId, long ipAddressId, int port, String protocol, long networkId, long accountId, long domainId, Purpose purpose, List sourceCidrs, Integer icmpCode, Integer icmpType, Long related) { this(xId, ipAddressId, port, port, protocol, networkId, accountId, domainId, purpose, sourceCidrs, icmpCode, icmpType, related, null); diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDao.java b/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDao.java index 24d9deb511c..42144b6bbcd 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDao.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDao.java @@ -30,4 +30,6 @@ public interface VpcGatewayDao extends GenericDao{ Long getNetworkAclIdForPrivateIp(long vpcId, long networkId, String ipaddr); List listByVpcIdAndType(long vpcId, VpcGateway.Type type); + + List listByAclIdAndType(long aclId, VpcGateway.Type type); } diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java index 6a2f8bd4459..a8cb2b38c43 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java @@ -41,6 +41,7 @@ public class VpcGatewayDaoImpl extends GenericDaoBase implem AllFieldsSearch.and("type", AllFieldsSearch.entity().getType(), SearchCriteria.Op.EQ); AllFieldsSearch.and("networkid", AllFieldsSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); AllFieldsSearch.and("ipaddress", AllFieldsSearch.entity().getIp4Address(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("aclId", AllFieldsSearch.entity().getNetworkACLId(), SearchCriteria.Op.EQ); AllFieldsSearch.done(); } @@ -86,4 +87,11 @@ public class VpcGatewayDaoImpl extends GenericDaoBase implem return listBy(sc); } + @Override + public List listByAclIdAndType(long aclId, VpcGateway.Type type) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("aclId", aclId); + sc.setParameters("type", type); + return listBy(sc); + } } diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java index fae315b01a0..6317f72d0df 100755 --- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java @@ -130,6 +130,9 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name = "is_persistent") boolean isPersistent; + @Column(name = "egress_default_policy") + boolean egressdefaultpolicy; + @Override public String getDisplayText() { return displayText; @@ -275,6 +278,10 @@ public class NetworkOfferingVO implements NetworkOffering { this.redundantRouter = redundantRouter; } + public boolean getEgressDefaultPolicy() { + return egressdefaultpolicy; + } + public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean specifyIpRanges, boolean isPersistent, boolean internalLb, boolean publicLb) { this.name = name; @@ -306,7 +313,7 @@ public class NetworkOfferingVO implements NetworkOffering { public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean dedicatedLb, boolean sharedSourceNat, boolean redundantRouter, boolean elasticIp, boolean elasticLb, - boolean specifyIpRanges, boolean inline, boolean isPersistent, boolean associatePublicIP, boolean publicLb, boolean internalLb) { + boolean specifyIpRanges, boolean inline, boolean isPersistent, boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean egressdefaultpolicy) { this(name, displayText, trafficType, systemOnly, specifyVlan, rateMbps, multicastRateMbps, isDefault, availability, tags, guestType, conserveMode, specifyIpRanges, isPersistent, internalLb, publicLb); this.dedicatedLB = dedicatedLb; this.sharedSourceNat = sharedSourceNat; @@ -315,6 +322,7 @@ public class NetworkOfferingVO implements NetworkOffering { this.elasticLb = elasticLb; this.inline = inline; this.eipAssociatePublicIp = associatePublicIP; + this.egressdefaultpolicy = egressdefaultpolicy; } public NetworkOfferingVO() { diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java index 909d7fe6325..b7363e7208a 100755 --- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java @@ -34,80 +34,90 @@ 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="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; + @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 +127,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 +141,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 +157,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 +167,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 +210,6 @@ public class DiskOfferingVO implements DiskOffering { this.name = name; } - @Override public boolean getSystemUse() { return systemUse; @@ -211,13 +223,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 +242,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 +303,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 +313,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; @@ -327,4 +339,36 @@ public class DiskOfferingVO implements DiskOffering { public void setDisplayOffering(boolean displayOffering) { this.displayOffering = displayOffering; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } 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..e30da0cbc2d 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,8 +26,11 @@ 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; + +//TODO: this will be removed after object_store merge. @Entity @Table(name = "s3") public class S3VO implements S3 { @@ -76,11 +76,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 +109,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, false); } 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 78b96ec9779..e3912740a48 100644 --- a/engine/schema/src/com/cloud/storage/SnapshotVO.java +++ b/engine/schema/src/com/cloud/storage/SnapshotVO.java @@ -25,100 +25,80 @@ 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="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 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="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; + @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 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(); @@ -156,19 +136,11 @@ 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() { return name; } + @Override public short getsnapshotType() { return snapshotType; @@ -182,22 +154,6 @@ public class SnapshotVO implements Snapshot { 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; - } - @Override public HypervisorType getHypervisorType() { return hypervisorType; @@ -208,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; @@ -222,6 +178,7 @@ public class SnapshotVO implements Snapshot { public String getTypeDescription() { return typeDescription; } + public void setTypeDescription(String typeDescription) { this.typeDescription = typeDescription; } @@ -248,30 +205,13 @@ public class SnapshotVO implements Snapshot { return state; } - - public void setState(State state) { + public void setState(State state) { 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)) { + for (Type type : Type.values()) { + if (type.equals(snapshotType)) { return type; } } @@ -286,13 +226,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/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 d761bf17e3b..63fadfac3e8 100755 --- a/engine/schema/src/com/cloud/storage/UploadVO.java +++ b/engine/schema/src/com/cloud/storage/UploadVO.java @@ -32,117 +32,114 @@ 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") +@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 hostId; + @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 - public long getHostId() { - return hostId; - } + @Override + public long getDataStoreId() { + return storeId; + } - public void setHostId(long hostId) { - this.hostId = hostId; - } + public void setDataStoreId(long hostId) { + this.storeId = hostId; + } - @Override + @Override public long getId() { - return id; - } + return id; + } - - public String getUuid() { + @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.hostId = 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.hostId = 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.hostId = hostId; + 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; this.typeId = typeId; this.lastUpdated = lastUpdated; this.uploadState = uploadState; @@ -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.hostId==other.getHostId() && 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 b8dfc41d51b..33732a419c9 100755 --- a/engine/schema/src/com/cloud/storage/VMTemplateHostVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateHostVO.java @@ -31,220 +31,218 @@ 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; /** * 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; - - @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; - - @Column (name="install_path") - private String installPath; - - @Column (name="url") - private String downloadUrl; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; - @Column(name="is_copy") - private boolean isCopy = false; - - @Column(name="destroyed") + @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; + + @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) + + @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 + + @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; - } - - @Override + return lastUpdated; + } + + @Override public void setLastUpdated(Date date) { - lastUpdated = date; - } - - @Override + lastUpdated = date; + } + + @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; @@ -253,8 +251,7 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj public long getSize() { return size; } - - + public void setPhysicalSize(long physicalSize) { this.physicalSize = physicalSize; } @@ -264,49 +261,50 @@ 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; - } - - @Override + public boolean isCopy() { + return isCopy; + } + + @Override public long getTemplateSize() { - return -1; - } - - @Override + return -1; + } + + @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() { // TODO Auto-generated method stub return this.state; } - + public long getUpdatedCount() { return this.updatedCount; } - + public void incrUpdatedCount() { this.updatedCount++; } @@ -314,9 +312,24 @@ 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(); + } + + @Override + public State getObjectInStoreState() { + 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 9b761764359..10ced67244f 100644 --- a/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java @@ -37,228 +37,239 @@ 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; - - @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; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + long id; - @Column(name="update_count", updatable = true, nullable=false) - protected long updatedCount; + @Column(name = "pool_id") + private long poolId; - @Column(name = "updated") - @Temporal(value = TemporalType.TIMESTAMP) - Date updated; + @Column(name = "template_id") + long templateId; - @Column(name = "state") - @Enumerated(EnumType.STRING) - ObjectInDataStoreStateMachine.State state; + @Column(name = GenericDaoBase.CREATED_COLUMN) + Date created = null; - @Override + @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) + 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; - } - - @Override + return installPath; + } + + @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; - } - - @Override + return lastUpdated; + } + + @Override public void setLastUpdated(Date date) { - lastUpdated = date; - } - - @Override + lastUpdated = date; + } + + @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; - } - - public void setTemplateSize(long templateSize) { - this.templateSize = templateSize; - } - - public boolean getMarkedForGC() { - return markedForGC; - } - - public void setMarkedForGC(boolean markedForGC) { - this.markedForGC = markedForGC; - } + return jobId; + } - @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; - } + public void setTemplateSize(long templateSize) { + this.templateSize = templateSize; + } - @Override - public int hashCode() { - Long tid = new Long(templateId); - Long hid = new Long(poolId); - return tid.hashCode()+hid.hashCode(); - } - - @Override + public boolean getMarkedForGC() { + return 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 int hashCode() { + Long tid = new Long(templateId); + Long hid = new Long(poolId); + return tid.hashCode() + hid.hashCode(); + } + + @Override public String toString() { - return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append("poolId").append("-").append(installPath).append("]").toString(); - } + return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append("poolId") + .append("-").append(installPath).append("]").toString(); + } @Override public State getState() { return this.state; } - + public long getUpdatedCount() { return this.updatedCount; } - + public void incrUpdatedCount() { this.updatedCount++; } @@ -266,10 +277,24 @@ 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(); + } + + @Override + public State getObjectInStoreState() { + 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 e643d75bf1e..3e711911f53 100755 --- a/engine/schema/src/com/cloud/storage/VMTemplateVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateVO.java @@ -41,106 +41,101 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateObject; @Entity -@Table(name="vm_template") -public class VMTemplateVO implements VirtualMachineTemplate, StateObject { +@Table(name = "vm_template") +public class VMTemplateVO implements VirtualMachineTemplate { @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 = "image_data_store_id") - private long imageDataStoreId; - + @Column(name = "size") private Long size; - - @Column(name = "state") - private TemplateState state; - - @Column(name="update_count", updatable = true) + + @Column(name = "update_count", updatable = true) protected long updatedCount; - + @Column(name = "updated") @Temporal(value = TemporalType.TIMESTAMP) Date updated; @@ -148,6 +143,9 @@ 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 3ac9e77fb5d..a58902121cc 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java +++ b/engine/schema/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; @@ -26,26 +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, long snapId); + 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); - 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); + 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 f55663fe204..f5319ea120a 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/engine/schema/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; @@ -51,12 +52,13 @@ 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()); - 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"; + // 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 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,15 +66,17 @@ 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; 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) { @@ -80,22 +84,21 @@ public class SnapshotDaoImpl extends GenericDaoBase implements sc.setParameters("prevSnapshotId", snapshotId); return findOneIncludingRemovedBy(sc); } - + @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); } @@ -103,42 +106,29 @@ public class SnapshotDaoImpl extends GenericDaoBase implements public List listByVolumeId(long volumeId) { return listByVolumeId(null, volumeId); } - + @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 - 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 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); @@ -147,51 +137,48 @@ 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(); - + /* + * 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(); - + 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); @@ -200,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); @@ -227,17 +216,18 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } } catch (Exception ex) { } - return null; + 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); @@ -265,7 +255,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } return 0; } - + @Override public long updateSnapshotSecHost(long dcId, long secHostId) { Transaction txn = Transaction.currentTxn(); @@ -285,32 +275,32 @@ 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(); - - if (status != null && status.length != 0) { - sc.setParameters("status", (Object[])status); - } - - sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready); - sc.setJoinParameters("instanceVolumes", "instanceId", instanceId); + 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(); - 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 @DB public boolean remove(Long id) { @@ -324,11 +314,11 @@ public class SnapshotDaoImpl extends GenericDaoBase implements txn.commit(); return result; } - + @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); } @@ -336,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 5394a8fa103..76359223bb3 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,40 +31,40 @@ 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(); sc.setParameters("volumeId", volumeId); return listBy(sc, filter); } - + @Override public Pair, Integer> listAndCountByVolumeId(long volumeId) { return listAndCountByVolumeId(volumeId, null); @@ -84,12 +83,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 31fad43e257..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().getHostId(), 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 7c66dd4b46b..c3d44bdb6aa 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java @@ -18,67 +18,62 @@ package com.cloud.storage.dao; import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; -import com.cloud.domain.DomainVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.storage.VMTemplateVO; -import com.cloud.template.VirtualMachineTemplate.TemplateFilter; -import com.cloud.user.Account; -import com.cloud.utils.Pair; import com.cloud.utils.db.GenericDao; 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 interface VMTemplateDao extends GenericDao { - //public void update(VMTemplateVO template); + public List listByPublic(); + public VMTemplateVO findByName(String templateName); - public List listAllSystemVMTemplates(); + public VMTemplateVO findByTemplateName(String templateName); - public List listDefaultBuiltinTemplates(); - public String getRoutingTemplateUniqueName(); - public List findIsosByIdAndPath(Long domainId, Long accountId, String path); - public List listReadyTemplates(); - public List listByAccountId(long accountId); - 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); + // public void update(VMTemplateVO template); - 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 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 long addTemplateToZone(VMTemplateVO tmplt, long zoneId); + + public List listAllInZone(long dataCenterId); + + public List listAllActive(); - public long addTemplateToZone(VMTemplateVO tmplt, long zoneId); - public List listAllInZone(long dataCenterId); - 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 d45ef73168b..e7b85f8a63f 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -16,25 +16,18 @@ // 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 +35,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; @@ -75,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); @@ -85,31 +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; - 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; @@ -120,15 +96,16 @@ 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; private SearchBuilder UserIsoSearch; private GenericSearchBuilder CountTemplatesByAccount; - private SearchBuilder updateStateSearch; - - @Inject ResourceTagDao _tagsDao; + // private SearchBuilder updateStateSearch; + @Inject + ResourceTagDao _tagsDao; private String routerTmpltName; private String consoleProxyTmpltName; @@ -138,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()) { @@ -172,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()) { @@ -209,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; @@ -219,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(); @@ -257,654 +236,527 @@ 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(); - 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(); + ActiveTmpltSearch = createSearchBuilder(); + ActiveTmpltSearch.and("removed", ActiveTmpltSearch.entity().getRemoved(), SearchCriteria.Op.NULL); - 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(); + 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(); - return result; - } +// 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 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) { - 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 (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); - } + VMTemplateVO tmplt2 = findById(tmplt.getId()); + if (tmplt2 == null) { + if (persist(tmplt) == null) { + throw new CloudRuntimeException("Failed to persist the template " + tmplt); } - - String attr = " AND "; - if (whereClause.endsWith(" WHERE ")) { - attr += " WHERE "; + if (tmplt.getDetails() != null) { + _templateDetailsDao.persist(tmplt.getId(), tmplt.getDetails()); } - - 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) + 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 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 "; - } - - if (!showDomr){ - sql += " AND t.type != '" +Storage.TemplateType.SYSTEM.toString() + "'"; - } + @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); + } - sql += " AND t.removed IS NULL"; + @Override + public List listAllActive() { + SearchCriteria sc = ActiveTmpltSearch.create(); + return listBy(sc); + } - return sql; - } + @Override + public List listDefaultBuiltinTemplates() { + SearchCriteria sc = tmpltTypeSearch.create(); + sc.setParameters("templateType", Storage.TemplateType.BUILTIN); + return listBy(sc); + } - 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 - 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; - } - } - - 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) { @@ -912,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); } @@ -943,185 +836,101 @@ 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, - 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) { - Long oldUpdated = vo.getUpdatedCount(); - Date oldUpdatedTime = vo.getUpdated(); + /* + * @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; } + */ - 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/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 bb3aa010116..67f7c3f64d7 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java @@ -22,12 +22,14 @@ import com.cloud.storage.VMTemplateZoneVO; 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 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..c4a4dc7230a 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java @@ -27,63 +27,73 @@ 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}) +@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(); - } - + public static final Logger s_logger = Logger.getLogger(VMTemplateZoneDaoImpl.class.getName()); - @Override - public List listByZoneId(long id) { - SearchCriteria sc = ZoneSearch.create(); - sc.setParameters("zone_id", id); - return listIncludingRemovedBy(sc); - } + protected final SearchBuilder ZoneSearch; + protected final SearchBuilder TemplateSearch; + protected final SearchBuilder ZoneTemplateSearch; - @Override - public List listByTemplateId(long templateId) { - SearchCriteria sc = TemplateSearch.create(); - sc.setParameters("template_id", templateId); - return listIncludingRemovedBy(sc); - } + public VMTemplateZoneDaoImpl() { + ZoneSearch = createSearchBuilder(); + ZoneSearch.and("zone_id", ZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); + ZoneSearch.done(); - @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); - } + TemplateSearch = createSearchBuilder(); + TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + TemplateSearch.done(); - @Override + 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 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 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) { + SearchCriteria sc = TemplateSearch.create(); + sc.setParameters("template_id", templateId); + Transaction txn = Transaction.currentTxn(); + txn.start(); + remove(sc); + txn.commit(); + + } } diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDao.java b/engine/schema/src/com/cloud/storage/dao/VolumeDao.java index 251318108d8..79c0dc37786 100755 --- a/engine/schema/src/com/cloud/storage/dao/VolumeDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeDao.java @@ -62,7 +62,7 @@ public interface VolumeDao extends GenericDao, 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/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/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index 8378eec005f..8f63a6c9485 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) { @@ -113,8 +128,8 @@ public class Upgrade410to420 implements DbUpgrade { } - private void updateSystemVmTemplates(Connection conn) { - + private void updateSystemVmTemplates(Connection conn) { + // TODO: system vm template migration after storage refactoring PreparedStatement pstmt = null; ResultSet rs = null; boolean xenserver = false; @@ -125,7 +140,7 @@ public class Upgrade410to420 implements DbUpgrade { s_logger.debug("Updating System Vm template IDs"); try{ //Get all hypervisors in use - try { + try { pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster` where removed is null"); rs = pstmt.executeQuery(); while(rs.next()){ @@ -313,6 +328,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'"); @@ -327,6 +343,8 @@ public class Upgrade410to420 implements DbUpgrade { } } } + */ + } private void updatePrimaryStore(Connection conn) { @@ -1131,8 +1149,8 @@ public class Upgrade410to420 implements DbUpgrade { } } } - - + + private void updateNetworksForPrivateGateways(Connection conn) { PreparedStatement pstmt = null; @@ -1150,7 +1168,7 @@ public class Upgrade410to420 implements DbUpgrade { pstmt.setLong(1, vpcId); pstmt.setLong(2, networkId); pstmt.executeUpdate(); - + } } catch (SQLException e) { throw new CloudRuntimeException("Failed to update private networks with VPC id.", e); @@ -1585,4 +1603,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) { + } + } + } } diff --git a/engine/schema/src/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/com/cloud/vm/VMInstanceVO.java index 973feb6f40d..cffdb345e7c 100644 --- a/engine/schema/src/com/cloud/vm/VMInstanceVO.java +++ b/engine/schema/src/com/cloud/vm/VMInstanceVO.java @@ -185,24 +185,24 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject _params; List _nics = new ArrayList(); - List _disks = new ArrayList(); + List _disks = new ArrayList(); StringBuilder _bootArgs = new StringBuilder(); Account _owner; BootloaderType _bootloader; @@ -137,7 +137,7 @@ public class VirtualMachineProfileImpl implements VirtualMachineProfile { _nics = nics; } - public void setDisks(List disks) { + public void setDisks(List disks) { _disks = disks; } @@ -147,7 +147,7 @@ public class VirtualMachineProfileImpl implements VirtualMachineProfile { } @Override - public List getDisks() { + public List getDisks() { return _disks; } @@ -157,7 +157,7 @@ public class VirtualMachineProfileImpl implements VirtualMachineProfile { } @Override - public void addDisk(int index, VolumeTO disk) { + public void addDisk(int index, DiskTO disk) { _disks.add(index, disk); } @@ -200,7 +200,7 @@ public class VirtualMachineProfileImpl implements VirtualMachineProfile { } @Override - public void addDisk(VolumeTO disk) { + public void addDisk(DiskTO disk) { _disks.add(disk); } diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 391fa5895b0..65b9d3b27c7 100755 --- a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.vm.dao; +import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; @@ -44,6 +45,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.JoinBuilder.JoinType; 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.Transaction; import com.cloud.utils.db.UpdateBuilder; @@ -103,6 +105,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im IdNetworkIdStatesSearch.done(); HostUpSearch = createSearchBuilder(); + HostUpSearch.select(null, Func.DISTINCT, HostUpSearch.entity().getId()); HostUpSearch.and("host", HostUpSearch.entity().getHostId(), Op.EQ); HostUpSearch.and("states", HostUpSearch.entity().getState(), Op.NIN); SearchBuilder joinRouterNetwork3 = _routerNetworkDao.createSearchBuilder(); @@ -112,6 +115,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im HostUpSearch.done(); StateNetworkTypeSearch = createSearchBuilder(); + StateNetworkTypeSearch.select(null, Func.DISTINCT, StateNetworkTypeSearch.entity().getId()); StateNetworkTypeSearch.and("state", StateNetworkTypeSearch.entity().getState(), Op.EQ); SearchBuilder joinRouterNetwork4 = _routerNetworkDao.createSearchBuilder(); joinRouterNetwork4.and("networkId", joinRouterNetwork4.entity().getNetworkId(), Op.EQ); @@ -214,7 +218,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("host", hostId); } sc.setJoinParameters("networkRouter", "type", Network.GuestType.Isolated); - return listBy(sc); + List routerIds = listBy(sc); + List routers = new ArrayList(); + for (DomainRouterVO router : routerIds) { + routers.add(findById(router.getId())); + } + return routers; } @Override @@ -253,7 +262,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("state", state); sc.setJoinParameters("networkRouter", "type", type); sc.setJoinParameters("host", "mgmtServerId", mgmtSrvrId); - return listBy(sc); + List routerIds = listBy(sc); + List routers = new ArrayList(); + for (DomainRouterVO router : routerIds) { + routers.add(findById(router.getId())); + } + return routers; } @Override diff --git a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java b/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java index 47f1d361216..aa765ad1bba 100644 --- a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java +++ b/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java @@ -32,5 +32,6 @@ public interface ApplicationLoadBalancerRuleDao extends GenericDao listBySourceIpAndNotRevoked(Ip sourceIp, long sourceNetworkId); List listLbIpsBySourceIpNetworkIdAndScheme(long sourceIpNetworkId, Scheme scheme); long countBySourceIpAndNotRevoked(Ip sourceIp, long sourceIpNetworkId); + long countActiveBySourceIp(Ip sourceIp, long sourceIpNetworkId); } diff --git a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java b/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java index 6036b5a2d60..67d0a78cd09 100644 --- a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java +++ b/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java @@ -43,6 +43,7 @@ public class ApplicationLoadBalancerRuleDaoImpl extends GenericDaoBase CountBy; protected final SearchBuilder NotRevokedSearch; final GenericSearchBuilder CountNotRevoked; + final GenericSearchBuilder CountActive; protected ApplicationLoadBalancerRuleDaoImpl() { @@ -77,6 +78,13 @@ public class ApplicationLoadBalancerRuleDaoImpl extends GenericDaoBase results = customSearch(sc, null); return results.get(0); } + + @Override + public long countActiveBySourceIp(Ip sourceIp, long sourceIpNetworkId) { + SearchCriteria sc = CountActive.create(); + sc.setParameters("sourceIp", sourceIp); + sc.setParameters("sourceIpNetworkId", sourceIpNetworkId); + sc.setParameters("state", State.Active); + List results = customSearch(sc, null); + return results.get(0); + } } diff --git a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java b/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java deleted file mode 100644 index cb49027f3bf..00000000000 --- a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cloudstack.storage.backup; - -public interface BackupMotionService { - boolean copySnapshot(String snapshotUri, String destSnapshotUri); -} 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/src/org/apache/cloudstack/storage/image/ImageDataStoreDriver.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java similarity index 80% rename from engine/storage/src/org/apache/cloudstack/storage/image/ImageDataStoreDriver.java rename to engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java index d352d972182..4259d9ed03f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/ImageDataStoreDriver.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; +package org.apache.cloudstack.storage.cache.allocator; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -public interface ImageDataStoreDriver extends DataStoreDriver { +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..f244a0371b7 --- /dev/null +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.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 org.apache.cloudstack.storage.cache.allocator; + +import java.util.Collections; +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 org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.storage.ScopeType; + +@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) { + 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 new file mode 100644 index 00000000000..4b4e52106ff --- /dev/null +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java @@ -0,0 +1,254 @@ +/* + * 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.storage.DataStoreRole; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.component.Manager; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.engine.subsystem.api.storage.*; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; +import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.log4j.Logger; + +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class StorageCacheManagerImpl implements StorageCacheManager, Manager { + private static final Logger s_logger = Logger.getLogger(StorageCacheManagerImpl.class); + @Inject + List storageCacheAllocator; + @Inject + DataMotionService dataMotionSvr; + @Inject + ObjectInDataStoreManager objectInStoreMgr; + @Inject + DataStoreManager dataStoreManager; + @Inject + StorageCacheReplacementAlgorithm cacheReplacementAlgorithm; + @Inject + ConfigurationDao configDao; + Boolean cacheReplacementEnabled = Boolean.TRUE; + int workers; + ScheduledExecutorService executors; + int cacheReplaceMentInterval; + + @Override + public DataStore getCacheStorage(Scope scope) { + for (StorageCacheAllocator allocator : storageCacheAllocator) { + DataStore store = allocator.getCacheStore(scope); + if (store != null) { + return store; + } + } + return null; + } + + protected List 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 + 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 { + 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; + } + + @Override + public boolean stop() { + // TODO Auto-generated method stub + return true; + } + + @Override + 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"); + DataObject dataObj = objectInStoreMgr.get(data, store); + dataObj.incRefCount(); + return dataObj; + } + + DataObject objOnCacheStore = store.create(data); + + AsyncCallFuture future = new AsyncCallFuture(); + CopyCommandResult result = null; + try { + objOnCacheStore.processEvent(Event.CreateOnlyRequested); + + dataMotionSvr.copyAsync(data, objOnCacheStore, future); + result = future.get(); + + if (result.isFailed()) { + objOnCacheStore.processEvent(Event.OperationFailed); + } else { + objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer()); + objOnCacheStore.incRefCount(); + 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()); + throw new CloudRuntimeException(e); + } finally { + if (result == null) { + 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; + } + + @Override + public boolean releaseCacheObject(DataObject data) { + data.decRefCount(); + return true; + } + + @Override + public boolean deleteCacheObject(DataObject data) { + return data.getDataStore().delete(data); + } +} \ No newline at end of file diff --git a/engine/storage/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/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/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/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/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java new file mode 100644 index 00000000000..631de6a47a3 --- /dev/null +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -0,0 +1,414 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.motion; + +import java.util.Map; + +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; +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.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.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; +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.VirtualMachineTO; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.host.Host; +import com.cloud.host.dao.HostDao; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; +import com.cloud.storage.VolumeManager; +import com.cloud.storage.dao.DiskOfferingDao; +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.snapshot.SnapshotManager; +import com.cloud.template.TemplateManager; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; + +@Component +public class AncientDataMotionStrategy implements DataMotionStrategy { + private static final Logger s_logger = Logger.getLogger(AncientDataMotionStrategy.class); + @Inject + EndPointSelector selector; + @Inject + TemplateManager templateMgr; + @Inject + VolumeDataStoreDao volumeStoreDao; + @Inject + HostDao hostDao; + @Inject + ConfigurationDao configDao; + @Inject + StorageManager storageMgr; + @Inject + VolumeDao volDao; + @Inject + VMTemplateDao templateDao; + @Inject + SnapshotManager snapshotMgr; + @Inject + SnapshotDao snapshotDao; + @Inject + SnapshotDataStoreDao _snapshotStoreDao; + @Inject + PrimaryDataStoreDao primaryDataStoreDao; + @Inject + DataStoreManager dataStoreMgr; + @Inject + TemplateDataStoreDao templateStoreDao; + @Inject + DiskOfferingDao diskOfferingDao; + @Inject + VMTemplatePoolDao templatePoolDao; + @Inject + VolumeManager volumeMgr; + @Inject + StorageCacheManager cacheMgr; + + @Override + public boolean canHandle(DataObject srcData, DataObject destData) { + // TODO Auto-generated method stub + return true; + } + + @Override + public boolean canHandle(Map volumeMap, Host srcHost, Host destHost) { + return false; + } + + 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; + } + + 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()); + int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, + Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); + Answer answer = null; + DataObject cacheData = null; + try { + if (needCacheStorage(srcData, destData)) { + // need to copy it to image cache store + 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); + 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); + } + if (cacheData != null) { + if (answer == null || !answer.getResult()) { + cacheMgr.deleteCacheObject(cacheData); + } else { + cacheMgr.releaseCacheObject(cacheData); + } + } + 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) { + DataObject leafData = null; + DataStore store = cacheMgr.getCacheStorage(snapshot.getDataStore().getScope()); + while (snapshot != null) { + DataObject cacheData = cacheMgr.createCacheObject(snapshot, store); + if (leafData == null) { + leafData = cacheData; + } + snapshot = snapshot.getParent(); + } + return leafData; + } + + protected void deleteSnapshotCacheChain(SnapshotInfo snapshot) { + while (snapshot != null) { + cacheMgr.deleteCacheObject(snapshot); + snapshot = snapshot.getParent(); + } + } + + 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 (!(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); + EndPoint ep = selector.select(snapObj, volObj); + Answer answer = ep.sendMessage(cmd); + + return answer; + } catch (Exception e) { + s_logger.error(basicErrMsg, e); + throw new CloudRuntimeException(basicErrMsg); + } finally { + if (!(storTO instanceof NfsTO)) { + deleteSnapshotCacheChain((SnapshotInfo) srcData); + } + } + } + + protected Answer cloneVolume(DataObject template, DataObject volume) { + CopyCommand cmd = new CopyCommand(template.getTO(), volume.getTO(), 0); + try { + EndPoint ep = selector.select(volume.getDataStore()); + Answer answer = ep.sendMessage(cmd); + return answer; + } catch (Exception e) { + s_logger.debug("Failed to send to storage pool", e); + throw new CloudRuntimeException("Failed to send to storage pool", e); + } + } + + protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) { + String value = configDao.getValue(Config.CopyVolumeWait.key()); + 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; + } + + 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 + 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); + } else { + answer = copyObject(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); + result.setResult(errMsg); + callback.complete(result); + return null; + } + + @DB + protected Answer createTemplateFromSnapshot(DataObject srcData, DataObject destData) { + + 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; + srcData = cacheSnapshotChain(snapshot); + } + + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _createprivatetemplatefromsnapshotwait); + 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()); + + 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; + } catch (Exception e) { + s_logger.debug("copy snasphot failed: " + e.toString()); + if (cacheData != null) { + cacheMgr.deleteCacheObject(cacheData); + } + throw new CloudRuntimeException(e.toString()); + } + + } + + @Override + public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, + AsyncCompletionCallback callback) { + CopyCommandResult result = new CopyCommandResult(null, null); + result.setResult("Unsupported operation requested for copying data."); + callback.complete(result); + + return null; + } +} 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 83% 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 b74e10c460f..22de0b25279 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java @@ -24,6 +24,8 @@ import java.util.Map; 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.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -40,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; } @@ -64,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/ImageServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java deleted file mode 100644 index 99b1013f964..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java +++ /dev/null @@ -1,235 +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; - -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.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageService; -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.TemplateEvent; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -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; -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.image.store.TemplateObject; -import org.apache.cloudstack.storage.motion.DataMotionService; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.utils.fsm.NoTransitionException; - -@Component -public class ImageServiceImpl implements ImageService { - private static final Logger s_logger = Logger.getLogger(ImageServiceImpl.class); - @Inject - ObjectInDataStoreManager objectInDataStoreMgr; - @Inject - DataObjectManager dataObjectMgr; - @Inject - DataMotionService motionSrv; - - 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(); - 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; - } - - DataObject templateOnStore = store.create(template); - 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; - } - - private class CopyTemplateContext extends AsyncRpcConext { - final AsyncCallFuture future; - final DataObject object; - /** - * @param callback - */ - public CopyTemplateContext(AsyncCompletionCallback callback, AsyncCallFuture future, DataObject object) { - super(callback); - this.future = future; - this.object = object; - } - - } - @Override - public AsyncCallFuture createTemplateFromSnapshotAsync( - SnapshotInfo snapshot, TemplateInfo template, DataStore store) { - AsyncCallFuture future = new AsyncCallFuture(); - DataObject templateOnStore = null; - try { - templateOnStore = store.create(template); - templateOnStore.processEvent(Event.CreateOnlyRequested); - - CopyTemplateContext context = new CopyTemplateContext(null, future, templateOnStore); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyTemplateAsyncCallback(null, null)) - .setContext(context); - this.motionSrv.copyAsync(snapshot, templateOnStore, caller); - } catch (Exception e) { - s_logger.debug("Failed to create template: " + template.getId() + "from snapshot: " + snapshot.getId() + ", due to " + e.toString()); - if (templateOnStore != null) { - try { - templateOnStore.processEvent(Event.OperationFailed); - } catch (Exception e1) { - - } - } - CommandResult result = new CommandResult(); - result.setResult(e.toString()); - future.complete(result); - } - return future; - } - - protected Void copyTemplateAsyncCallback(AsyncCallbackDispatcher callback, CopyTemplateContext context) { - CopyCommandResult result = callback.getResult(); - AsyncCallFuture future = context.future; - DataObject object = context.object; - CommandResult res = new CommandResult(); - if (result.isFailed()) { - res.setResult(result.getResult()); - object.processEvent(Event.OperationFailed); - } else { - object.processEvent(Event.OperationSuccessed); - } - future.complete(res); - return null; - } - - @Override - public AsyncCallFuture createTemplateFromVolumeAsync( - VolumeInfo volume, TemplateInfo template, DataStore store) { - AsyncCallFuture future = new AsyncCallFuture(); - DataObject templateOnStore = null; - try { - templateOnStore = store.create(template); - templateOnStore.processEvent(Event.CreateOnlyRequested); - - CopyTemplateContext context = new CopyTemplateContext(null, future, templateOnStore); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyTemplateAsyncCallback(null, null)) - .setContext(context); - this.motionSrv.copyAsync(volume, templateOnStore, caller); - } catch (Exception e) { - s_logger.debug("Failed to create template: " + template.getId() + "from volume: " + volume.getId() + ", due to " + e.toString()); - if (templateOnStore != null) { - try { - templateOnStore.processEvent(Event.OperationFailed); - } catch (Exception e1) { - - } - } - CommandResult result = new CommandResult(); - result.setResult(e.toString()); - future.complete(result); - } - return future; - } -} 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 61% 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 616e4789a27..e369c1c033e 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 @@ -21,42 +21,42 @@ package org.apache.cloudstack.storage.image; 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.DataStoreRole; -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.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; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; @Component -public class ImageDataFactoryImpl implements ImageDataFactory { - private static final Logger s_logger = Logger - .getLogger(ImageDataFactoryImpl.class); +public class TemplateDataFactoryImpl implements TemplateDataFactory { + private static final Logger s_logger = Logger.getLogger(TemplateDataFactoryImpl.class); @Inject VMTemplateDao imageDataDao; @Inject - ObjectInDataStoreManager objMap; - @Inject DataStoreManager storeMgr; @Inject 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. boolean found = false; if (store.getRole() == DataStoreRole.Primary) { VMTemplateStoragePoolVO templatePoolVO = templatePoolDao.findByPoolTemplate(store.getId(), templateId); @@ -64,28 +64,40 @@ public class ImageDataFactoryImpl implements ImageDataFactory { found = true; } } else { - DataObjectInStore obj = objMap.findObject(templ.getUuid(), DataObjectType.TEMPLATE, store.getUuid(), store.getRole()); - if (obj != null) { + TemplateDataStoreVO templateStoreVO = templateStoreDao.findByStoreTemplate(store.getId(), templateId); + if (templateStoreVO != null) { found = true; } } - + if (!found) { 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) { - VMTemplateVO templ = imageDataDao.findById(templateId); - if (templ.getImageDataStoreId() == null) { - return this.getTemplate(templateId, null); - } - DataStore store = this.storeMgr.getDataStore(templ.getImageDataStoreId(), DataStoreRole.Image); + public TemplateInfo getTemplate(long templateId, DataStoreRole storeRole) { + TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplate(templateId, storeRole); + DataStore store = null; + if (tmplStore != null) { + store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole); + } return this.getTemplate(templateId, store); } + + @Override + public TemplateInfo getTemplate(long templateId, DataStoreRole storeRole, Long zoneId) { + TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplateZone(templateId, zoneId, storeRole); + DataStore store = 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 new file mode 100644 index 00000000000..96c35f36f34 --- /dev/null +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -0,0 +1,610 @@ +/* + * 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.io.File; +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.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.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; +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; +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.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; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +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.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.ResourceAllocationException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.StoragePool; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateVO; +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.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; +import com.cloud.utils.fsm.NoTransitionException; + +@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 + DataMotionService _motionSrv; + @Inject + ResourceLimitService _resourceLimitMgr; + @Inject + AccountManager _accountMgr; + @Inject + AlertManager _alertMgr; + @Inject + VMTemplateDao _templateDao; + @Inject + TemplateDataStoreDao _vmTemplateStoreDao; + @Inject + DataCenterDao _dcDao = null; + @Inject + VMTemplateZoneDao _vmTemplateZoneDao; + @Inject + ClusterDao _clusterDao; + @Inject + TemplateDataFactory _templateFactory; + @Inject + VMTemplatePoolDao _tmpltPoolDao; + @Inject + EndPointSelector _epSelector; + @Inject + TemplateManager _tmpltMgr; + + class TemplateOpContext extends AsyncRpcConext { + final TemplateObject template; + final AsyncCallFuture future; + + public TemplateOpContext(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 void createTemplateAsync(TemplateInfo template, DataStore store, + AsyncCompletionCallback callback) { + // persist template_store_ref entry + TemplateObject templateOnStore = (TemplateObject) store.create(template); + // update template_store_ref and template state + try { + templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); + } catch (Exception e) { + TemplateApiResult result = new TemplateApiResult(templateOnStore); + result.setResult(e.toString()); + result.setSuccess(false); + if (callback != null) { + callback.complete(result); + } + return; + } + + TemplateOpContext context = new TemplateOpContext(callback, + templateOnStore, null); + + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context); + store.getDriver().createAsync(templateOnStore, caller); + } + + @Override + public void downloadBootstrapSysTemplate(DataStore store) { + Set toBeDownloaded = new HashSet(); + + List rtngTmplts = _templateDao.listAllSystemVMTemplates(); + + for (VMTemplateVO rtngTmplt : rtngTmplts) { + 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) { + 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); + } + } + } + } + + @Override + public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) { + Set toBeDownloaded = new HashSet(); + List stores = _storeMgr.getImageStoresByScope(new ZoneScope(dcId)); + if (stores == null || stores.isEmpty()) { + return; + } + + /* 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); + } + } + + for (VMTemplateVO builtinTmplt : defaultBuiltin) { + if (builtinTmplt.getHypervisorType() == hostHyper) { + toBeDownloaded.add(builtinTmplt); + } + } + + 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); + } + } + } + } + + @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.listAllActive(); + } 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 image store"); + 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()); + // 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 && tmplt.getUrl() != null) { + 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(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()); + } + } + } + _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()); + tmpltStore.setDataStoreRole(store.getRole()); + _vmTemplateStoreDao.persist(tmpltStore); + + // update size in vm_template table + VMTemplateVO tmlpt = _templateDao.findById(tmplt.getId()); + tmlpt.setSize(tmpltInfo.getSize()); + _templateDao.update(tmplt.getId(), tmlpt); + associateTemplateToZone(tmplt.getId(), zoneId); + + + } + } 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()); + } + } + } + + 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, skip + if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) { + continue; + } + if (availHypers.contains(tmplt.getHypervisorType())) { + 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); + } + } + } + + for (String uniqueName : templateInfos.keySet()) { + TemplateProp tInfo = templateInfos.get(uniqueName); + if (_tmpltMgr.templateIsDeleteable(tInfo.getId())) { + // we cannot directly call deleteTemplateSync here to + // reuse delete logic since in this case, our db does not have + // this template at all. + 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()) { + 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); + } + + } + } + + } + + // 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 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; + return tanswer.getTemplateInfo(); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("can not list template for secondary storage host " + ssStore.getId()); + } + } + + return null; + } + + protected Void createTemplateCallback(AsyncCallbackDispatcher callback, + TemplateOpContext context) { + TemplateObject template = context.getTemplate(); + AsyncCompletionCallback parentCallback = context.getParentCallback(); + TemplateApiResult result = new TemplateApiResult(template); + CreateCmdResult callbackResult = callback.getResult(); + if (callbackResult.isFailed()) { + template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); + result.setResult(callbackResult.getResult()); + if (parentCallback != null) { + parentCallback.complete(result); + } + return null; + } + + try { + template.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); + } catch (Exception e) { + result.setResult(e.toString()); + if (parentCallback != null) { + parentCallback.complete(result); + } + return null; + } + + if (parentCallback != null) { + parentCallback.complete(result); + } + return null; + } + + @Override + public AsyncCallFuture deleteTemplateAsync(TemplateInfo template) { + TemplateObject to = (TemplateObject) template; + // update template_store_ref status + to.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); + + AsyncCallFuture future = new AsyncCallFuture(); + + 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, + TemplateOpContext context) { + CommandResult result = callback.getResult(); + TemplateObject vo = context.getTemplate(); + 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()); + context.future.complete(apiResult); + 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); + _motionSrv.copyAsync(source, templateOnStore, caller); + return future; + } + + @Override + public AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, + TemplateInfo template, DataStore store) { + return copyAsync(snapshot, template, store); + } + + @Override + public AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, + DataStore store) { + return copyAsync(volume, template, store); + } + + @Override + public AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore) { + return copyAsync(srcTemplate, srcTemplate, destStore); + } + + @Override + public AsyncCallFuture prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool) { + return copyAsync(srcTemplate, srcTemplate, (DataStore) pool); + } + + protected Void copyTemplateCallBack(AsyncCallbackDispatcher callback, + TemplateOpContext context) { + TemplateInfo destTemplate = context.getTemplate(); + 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); + } else { + destTemplate.processEvent(Event.OperationSuccessed, result.getAnswer()); + } + future.complete(res); + } catch (Exception e) { + s_logger.debug("Failed to process copy template callback", e); + res.setResult(e.toString()); + future.complete(res); + } + + return null; + } + + @Override + public void addSystemVMTemplatesToSecondary(DataStore store) { + long storeId = store.getId(); + List rtngTmplts = _templateDao.listAllSystemVMTemplates(); + for (VMTemplateVO tmplt : rtngTmplts) { + 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()); + tmpltStore.setSize(0L); + 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/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/driver/AncientImageDataStoreDriverImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/AncientImageDataStoreDriverImpl.java deleted file mode 100644 index 4c16f2fe4b1..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/AncientImageDataStoreDriverImpl.java +++ /dev/null @@ -1,254 +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.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.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; -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.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.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 AncientImageDataStoreDriverImpl implements ImageDataStoreDriver { - private static final Logger s_logger = Logger - .getLogger(AncientImageDataStoreDriverImpl.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 PrimaryDataStoreDao primaryDataStoreDao; - @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(); - VolumeVO volume = volumeDao.findById(volumeId); - StoragePoolVO pool = primaryDataStoreDao.findById(volume.getPoolId()); - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - pool, 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/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java deleted file mode 100644 index 3d46c73cde2..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java +++ /dev/null @@ -1,126 +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.driver; - -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.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 com.cloud.storage.dao.VMTemplateDao; - -//http-read-only based image store -public class DefaultImageDataStoreDriverImpl implements ImageDataStoreDriver { - @Inject - EndPointSelector selector; - @Inject - VMTemplateDao imageDataDao; - public DefaultImageDataStoreDriverImpl() { - } - - @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.getUri()); - 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); - } - - @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 - - } -} 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 83e98878158..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -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); - } - - @Override - public StateMachine2 getStateMachine() { - return stateMachine; - } -} 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/ImageDataStoreManagerImpl.java deleted file mode 100644 index bc546f8d0c1..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreManagerImpl.java +++ /dev/null @@ -1,94 +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 java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -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.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.ImageDataStoreManager; -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.springframework.stereotype.Component; - -import com.cloud.storage.dao.VMTemplateDao; - -@Component -public class ImageDataStoreManagerImpl implements ImageDataStoreManager { - @Inject - ImageDataStoreDao dataStoreDao; - @Inject - VMTemplateDao imageDataDao; - @Inject - DataStoreProviderManager providerManager; - Map driverMaps; - - @PostConstruct - public void config() { - driverMaps = new HashMap(); - } - - @Override - public ImageDataStore getImageDataStore(long dataStoreId) { - ImageDataStoreVO dataStore = dataStoreDao.findById(dataStoreId); - String providerName = dataStore.getProviderName(); - ImageDataStoreProvider provider = (ImageDataStoreProvider)providerManager.getDataStoreProvider(providerName); - ImageDataStore imgStore = DefaultImageDataStoreImpl.getDataStore(dataStore, - driverMaps.get(provider.getName()), provider - ); - // TODO Auto-generated method stub - return imgStore; - } - - @Override - public boolean registerDriver(String providerName, ImageDataStoreDriver driver) { - if (driverMaps.containsKey(providerName)) { - return false; - } - driverMaps.put(providerName, driver); - return true; - } - - @Override - public ImageDataStore getImageDataStore(String uuid) { - ImageDataStoreVO dataStore = dataStoreDao.findByUuid(uuid); - return getImageDataStore(dataStore.getId()); - } - - @Override - public List getList() { - List stores = dataStoreDao.listAll(); - List imageStores = new ArrayList(); - for (ImageDataStoreVO store : stores) { - imageStores.add(getImageDataStore(store.getId())); - } - return imageStores; - } - -} 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 new file mode 100644 index 00000000000..64ef78f8e09 --- /dev/null +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java @@ -0,0 +1,130 @@ +/* + * 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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.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; +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; + +@Component +public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager { + private static final Logger s_logger = Logger.getLogger(ImageStoreProviderManagerImpl.class); + @Inject + ImageStoreDao dataStoreDao; + @Inject + VMTemplateDao imageDataDao; + @Inject + DataStoreProviderManager providerManager; + Map driverMaps; + + @PostConstruct + 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, driverMaps.get(provider.getName()), provider); + return imgStore; + } + + @Override + public boolean registerDriver(String providerName, ImageStoreDriver driver) { + if (driverMaps.containsKey(providerName)) { + return false; + } + driverMaps.put(providerName, driver); + return true; + } + + @Override + public ImageStoreEntity getImageStore(String uuid) { + ImageStoreVO dataStore = dataStoreDao.findByUuid(uuid); + return getImageStore(dataStore.getId()); + } + + @Override + public List listImageStores() { + List stores = dataStoreDao.listImageStores(); + List imageStores = new ArrayList(); + for (ImageStoreVO store : stores) { + imageStores.add(getImageStore(store.getId())); + } + return imageStores; + } + + @Override + public List listImageStoresByScope(ZoneScope scope) { + List stores = dataStoreDao.findByScope(scope); + 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; + } + + @Override + public List listImageCacheStores(Scope scope) { + if (scope.getScopeType() != ScopeType.ZONE) { + s_logger.debug("only support zone wide image cache stores"); + return null; + } + 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/DefaultImageDataStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java similarity index 50% 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/ImageStoreImpl.java index 6eefc6f43f8..6d8e8e59c6f 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/ImageStoreImpl.java @@ -18,112 +18,113 @@ */ package org.apache.cloudstack.storage.image.store; +import java.util.Date; import java.util.Set; +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.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.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.command.CommandResult; 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.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; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.component.ComponentContext; -import com.cloud.utils.storage.encoding.EncodingType; - -public class DefaultImageDataStoreImpl implements ImageDataStore { +public class ImageStoreImpl implements ImageStoreEntity { + private static final Logger s_logger = Logger.getLogger(ImageStoreImpl.class); @Inject VMTemplateDao imageDao; @Inject private ObjectInDataStoreManager objectInStoreMgr; - protected ImageDataStoreDriver driver; - protected ImageDataStoreVO imageDataStoreVO; - protected ImageDataStoreProvider provider; - boolean needDownloadToCacheStorage = false; + @Inject + private CapacityDao capacityDao; + protected ImageStoreDriver driver; + protected ImageStoreVO imageDataStoreVO; + protected ImageStoreProvider provider; - public DefaultImageDataStoreImpl() { - + public ImageStoreImpl() { + super(); } - - 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) { - DefaultImageDataStoreImpl instance = (DefaultImageDataStoreImpl)ComponentContext.inject(DefaultImageDataStoreImpl.class); + public static ImageStoreEntity getDataStore(ImageStoreVO dataStoreVO, ImageStoreDriver imageDataStoreDriver, + ImageStoreProvider provider) { + ImageStoreImpl instance = ComponentContext.inject(ImageStoreImpl.class); instance.configure(dataStoreVO, imageDataStoreDriver, provider); return instance; } @Override public Set listTemplates() { - // TODO Auto-generated method stub return null; } @Override public DataStoreDriver getDriver() { - // TODO Auto-generated method stub return this.driver; } @Override public DataStoreRole getRole() { - // TODO Auto-generated method stub - return DataStoreRole.Image; + return this.imageDataStoreVO.getRole(); } + @Override public long getId() { - // TODO Auto-generated method stub return this.imageDataStoreVO.getId(); } @Override public String getUri() { - return this.imageDataStoreVO.getProtocol() + "://" + "?" + EncodingType.ROLE + "=" + this.getRole(); + return this.imageDataStoreVO.getUrl(); } @Override public Scope getScope() { - return new ZoneScope(imageDataStoreVO.getDcId()); + return new ZoneScope(imageDataStoreVO.getDataCenterId()); } @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; } @Override public boolean exists(DataObject object) { - return (objectInStoreMgr.findObject(object, - this) != null) ? true : false; + return (objectInStoreMgr.findObject(object, this) != null) ? true : false; } @Override @@ -131,6 +132,10 @@ public class DefaultImageDataStoreImpl implements ImageDataStore { return this.imageDataStoreVO.getUuid(); } + public Date getCreated() { + return this.imageDataStoreVO.getCreated(); + } + @Override public DataObject create(DataObject obj) { DataObject object = objectInStoreMgr.create(obj, this); @@ -139,7 +144,55 @@ public class DefaultImageDataStoreImpl implements ImageDataStore { @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 + public String getName() { + return imageDataStoreVO.getName(); + } + + @Override + public Long getDataCenterId() { + return imageDataStoreVO.getDataCenterId(); + } + + @Override + public String getProviderName() { + return imageDataStoreVO.getProviderName(); + } + + @Override + public String getProtocol() { + return imageDataStoreVO.getProtocol(); + } + + @Override + public DataStoreTO getTO() { + return getDriver().getStoreTO(this); + } + + @Override + public String getMountPoint() { + return imageDataStoreVO.getParent(); + } + + @Override + public String createEntityExtractUrl(String installPath, ImageFormat format) { + return driver.createEntityExtractUrl(this, installPath, format); + } + + } 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..b093cbd6a2c 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,40 +18,52 @@ */ 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; -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; 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.image.manager.ImageDataManager; +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.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; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.VMTemplateStoragePoolVO; +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; 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 - .getLogger(TemplateObject.class); + private static final Logger s_logger = Logger.getLogger(TemplateObject.class); private VMTemplateVO imageVO; private DataStore dataStore; @Inject - ImageDataManager imageMgr; - @Inject VMTemplateDao imageDao; @Inject - ObjectInDataStoreManager ojbectInStoreMgr; - @Inject VMTemplatePoolDao templatePoolDao; + ObjectInDataStoreManager objectInStoreMgr; + @Inject + VMTemplatePoolDao templatePoolDao; + @Inject + TemplateDataStoreDao templateStoreDao; public TemplateObject() { } @@ -67,10 +79,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); } @@ -84,6 +92,11 @@ public class TemplateObject implements TemplateInfo { return this.dataStore; } + @Override + public String getUniqueName() { + return this.imageVO.getUniqueName(); + } + @Override public long getId() { return this.imageVO.getId(); @@ -97,27 +110,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); - 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 image.getUrl(); + } @Override @@ -127,28 +122,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(); @@ -160,24 +148,304 @@ 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 { - 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) { try { - ojbectInStoreMgr.update(this, event); + 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) { + 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.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()); + } finally { + // in case of OperationFailed, expunge the entry + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { + objectInStoreMgr.delete(this); + } } } + + @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.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) { + 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.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) { + 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) { + objectInStoreMgr.delete(this); + } + } + } + + @Override + public void incRefCount() { + if (this.dataStore == null) { + return; + } + + 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); + } + } + + @Override + public void decRefCount() { + if (this.dataStore == null) { + return; + } + 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); + } + } + + @Override + public Long getRefCount() { + if (this.dataStore == null) { + return null; + } + if (this.dataStore.getRole() == DataStoreRole.Image || this.dataStore.getRole() == DataStoreRole.ImageCache) { + TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), this.getId()); + return store.getRefCnt(); + } + return null; + } + + @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); + } + } + + return to; + } + + @Override + public String getInstallPath() { + if (this.dataStore == null) { + return null; + } + DataObjectInStore obj = objectInStoreMgr.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 Boolean isDynamicallyScalable() { + return Boolean.FALSE; + } + + @Override + public long getDomainId() { + return this.imageVO.getDomainId(); + } + + @Override + public boolean delete() { + if (dataStore != null) { + return dataStore.delete(this); + } + return true; + } + } 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/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 1c21496871f..00000000000 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java +++ /dev/null @@ -1,158 +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.Map; - -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.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.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; -import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.host.Host; - -//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.setSuccess(answer.getResult()); - result.setResult(answer.getDetails()); - } else { - TemplateOnPrimaryDataStoreInfo templateStore = context.getTemplate(); - templateStore.setPath(answer.getPath()); - result.setSuccess(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 boolean canHandle(Map volumeMap, Host srcHost, Host destHost) { - 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; - - } - - @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, - AsyncCompletionCallback callback) { - CopyCommandResult result = new CopyCommandResult("", null); - result.setResult("not implemented"); - callback.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/pom.xml b/engine/storage/integration-test/pom.xml index 1bce37afd23..8a9dc15579c 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,48 @@ ${project.version} test
+ + org.apache.cloudstack + cloud-plugin-hypervisor-vmware + ${project.version} + test + + + org.apache.cloudstack + cloud-plugin-hypervisor-kvm + ${project.version} + test + + + org.apache.cloudstack + cloud-plugin-storage-volume-default + ${project.version} + test + + + org.apache.cloudstack + cloud-secondary-storage + ${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/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java new file mode 100644 index 00000000000..4d932964a64 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.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 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.URL; +import java.util.HashMap; +import java.util.List; + +import javax.naming.ConfigurationException; + +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.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.StorageLayer; +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 NfsSecondaryStorageResource { + + 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(); + } + + createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), + "create_privatetemplate_from_snapshot_xen.sh"); + + } + + @Override + public String getRootDir(String secUrl) { + return "/mnt"; + } + + @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); + URL urlObj; + try { + urlObj = new URL(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/allocator/StorageAllocatorTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java index 9444fa5246e..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 @@ -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; @@ -28,7 +26,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; @@ -37,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; @@ -55,6 +53,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; @@ -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("ancient 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.setUsedBytes(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("ancient 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.setUsedBytes(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/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/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 0dcdebd6553..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 @@ -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.cache.manager.StorageCacheManagerImpl; import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library; import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; @@ -43,15 +43,19 @@ 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.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; @@ -61,6 +65,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; @@ -70,11 +75,16 @@ 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.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.vm.VirtualMachineManager; import com.cloud.vm.dao.ConsoleProxyDaoImpl; @@ -85,137 +95,138 @@ import com.cloud.vm.dao.UserVmDaoImpl; import com.cloud.vm.dao.UserVmDetailsDaoImpl; 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, - HostDaoImpl.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, - UserDaoImpl.class - -}, -includeFilters={@Filter(value=Library.class, type=FilterType.CUSTOM)}, -useDefaultFilters=false -) +@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 EndPointSelector selector() { - return Mockito.mock(EndPointSelector.class); - } - @Bean - public AgentManager agentMgr() { - return new DirectAgentManagerSimpleImpl(); - } - @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); + } + public static class Library implements TypeFilter { @Override 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..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 @@ -24,7 +24,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; import org.testng.annotations.Test; -import com.cloud.utils.db.DB; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.Transaction; public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { @@ -35,36 +35,49 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String templateUrl; private String localStorageUuid; private String primaryStorageUrl; + private String secondaryStorage; + private String imageInstallPath; + private String scriptPath; + private HypervisorType hypervisor; private Transaction txn; - + + private String s3AccessKey; + private String s3SecretKey; + private String s3EndPoint; + private String s3TemplateBucket; + private String primaryStorageUuid; + private boolean s3UseHttps; + protected void injectMockito() { - + } - + @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(); } - + @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"}) - protected void setup(String hostuuid, String gateway, String cidr, - String hostIp, String templateUrl, String localStorageUuid, - String primaryStorage) { + @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; @@ -72,33 +85,108 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.templateUrl = templateUrl; this.localStorageUuid = localStorageUuid; this.primaryStorageUrl = primaryStorage; + this.primaryStorageUuid = primaryStorageUuid; + this.imageInstallPath = imageInstallPath; + this.hypervisor = HypervisorType.getType(hypervisor); + 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); + this.scriptPath = scriptPath; + if (this.scriptPath != null) { + System.setProperty("paths.script", this.getScriptPath()); + } } - + 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; } + + public String getSecondaryStorage() { + return secondaryStorage; + } + + 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; + } + + public String getImageInstallPath() { + return imageInstallPath; + } + + public void setImageInstallPath(String imageInstallPath) { + this.imageInstallPath = imageInstallPath; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getScriptPath() { + return scriptPath; + } + + public void setScriptPath(String scriptPath) { + 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 f4a970bae58..8c4571f8c88 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; @@ -32,23 +34,38 @@ import com.cloud.agent.StartupCommandProcessor; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; 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.kvm.resource.LibvirtComputingResource; +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 final 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 @@ -75,7 +92,15 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa @Override public Answer easySend(Long hostId, Command cmd) { - // TODO Auto-generated method stub + 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; } @@ -92,14 +117,50 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa ServerResource resource = null; if (host.getHypervisorType() == HypervisorType.XenServer) { resource = new XcpOssResource(); - } - try { resource.configure(host.getName(), params); - hostResourcesMap.put(hostId, resource); + } 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(); + 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(); + } + } + + hostResourcesMap.put(hostId, resource); HostEnvironment env = new HostEnvironment(); SetupCommand cmd = new SetupCommand(env); cmd.setNeedSetup(true); @@ -108,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); @@ -130,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; } @@ -171,24 +234,19 @@ 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) { // TODO Auto-generated method stub return false; } + @Override + public AgentAttache handleDirectConnectAgent(HostVO host, StartupCommand[] cmds, ServerResource resource, + boolean forRebalance) throws ConnectionException { + // TODO Auto-generated method stub + return null; + } + @Override public boolean agentStatusTransitTo(HostVO host, Event e, long msId) { // 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 fc4aea85822..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 @@ -22,14 +22,14 @@ import java.util.UUID; import javax.inject.Inject; -import org.apache.cloudstack.storage.to.ImageDataStoreTO; -import org.apache.cloudstack.storage.to.ImageOnPrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.TemplateTO; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; +import org.apache.cloudstack.storage.to.ImageStoreTO; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; + import com.cloud.agent.AgentManager; import com.cloud.agent.api.Command; import com.cloud.agent.api.ReadyCommand; @@ -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,39 +65,40 @@ public class DirectAgentTest extends CloudStackTestNGBase { private long dcId; private long clusterId; private long hostId; - + @Test(priority = -1) public void setUp() { - HostVO host = hostDao.findByGuid(this.getHostGuid()); + HostVO host = hostDao.findByGuid(getHostGuid()); if (host != null) { hostId = host.getId(); dcId = host.getDataCenterId(); 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(), this.getHostGateway(), this.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(this.getHostGuid()); + host = new HostVO(getHostGuid()); host.setName("devcloud xen host"); host.setType(Host.Type.Routing); host.setHypervisorType(HypervisorType.XenServer); - host.setPrivateIpAddress(this.getHostIp()); + host.setPrivateIpAddress(getHostIp()); host.setDataCenterId(dc.getId()); host.setVersion("6.0.1"); host.setAvailable(true); @@ -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() { - ImageOnPrimaryDataStoreTO image = Mockito.mock(ImageOnPrimaryDataStoreTO.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); - - ImageDataStoreTO imageStore = Mockito.mock(ImageDataStoreTO.class); - Mockito.when(imageStore.getType()).thenReturn("http"); - - TemplateTO template = Mockito.mock(TemplateTO.class); - Mockito.when(template.getPath()).thenReturn(this.getTemplateUrl()); - Mockito.when(template.getImageDataStore()).thenReturn(imageStore); - - Mockito.when(image.getTemplate()).thenReturn(template); - //CopyTemplateToPrimaryStorageCmd cmd = new CopyTemplateToPrimaryStorageCmd(image); + Mockito.when(primaryStore.getUuid()).thenReturn(getLocalStorageUuid()); + // 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.getDataStore()).thenReturn(imageStore); + + // 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 4ec2436b06d..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.HypervisorHostEndPoint; -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(HypervisorHostEndPoint 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(HypervisorHostEndPoint 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 8fc161bae1e..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.HypervisorHostEndPoint; - -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(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { - executor.schedule(new MockRpcCallBack(command, callback), 10, TimeUnit.SECONDS); - } - - @Override - public Answer sendCommand(HypervisorHostEndPoint 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 new file mode 100644 index 00000000000..74caba3a86c --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.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 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; + +public class MockLocalHostEndPoint extends LocalHostEndpoint { + @Override + public Answer sendMessage(Command cmd) { + if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand) + || (cmd instanceof DeleteCommand)) { + 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 a84f3087d59..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 @@ -21,11 +21,11 @@ package org.apache.cloudstack.storage.test; import java.util.Map; 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.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.motion.DataMotionStrategy; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; @@ -44,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 new file mode 100644 index 00000000000..0bb724d10e4 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java @@ -0,0 +1,180 @@ +// 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; +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.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; +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; +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.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; + @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(); + + // 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); + + // 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); + 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); + } + + @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() { + 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 new file mode 100644 index 00000000000..2579a38157d --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -0,0 +1,500 @@ +/* + * 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.List; +import java.util.UUID; +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; +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.ObjectInDataStoreStateMachine.Event; +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.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; +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; +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.mockito.Matchers; +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.agent.api.Command; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenter.NetworkType; +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.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.hypervisor.HypervisorGuruManager; +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.Storage.ImageFormat; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; +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 + 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 + HypervisorGuruManager hyGuruMgr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + ResourceManager resourceMgr; + @Inject + VolumeDataFactory volFactory; + @Inject + SnapshotDataFactory snapshotFactory; + @Inject + List snapshotStrategies; + @Inject + SnapshotService snapshotSvr; + @Inject + SnapshotDao snapshotDao; + @Inject + EndPointSelector epSelector; + @Inject + VolumeDao volumeDao; + + long primaryStoreId; + VMTemplateVO image; + String imageStoreName = "testImageStore"; + RemoteHostEndPoint remoteEp; + + @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(this.getHypervisor().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(this.getHypervisor()); + host.setClusterId(cluster.getId()); + + host = hostDao.persist(host); + + imageStore = new ImageStoreVO(); + imageStore.setName(imageStoreName); + 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); + } + + 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()); + to.setFormat(ImageFormat.VHD); + to.setSize(1000L); + 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) 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(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()); + + } + + 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(DataStoreProvider.DEFAULT_PRIMARY); + 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(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000); + volume.setDataCenterId(this.dcId); + volume.setPoolId(dataStoreId); + volume = volumeDao.persist(volume); + return volume; + } + + public VolumeInfo createCopyBaseImage() throws InterruptedException, ExecutionException { + 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)); + + VolumeApiResult result; + result = future.get(); + Assert.assertTrue(result.isSuccess()); + return result.getVolume(); + + } + + + + private VMTemplateVO createTemplateInDb() { + VMTemplateVO 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 createVolumeFromSnapshot() throws InterruptedException, ExecutionException { + 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()); + AsyncCallFuture volFuture = this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot); + VolumeApiResult apiResult = volFuture.get(); + Assert.assertTrue(apiResult.isSuccess()); + } + + @Test + public void deleteSnapshot() 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); + + // create another snapshot + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + strategy.deleteSnapshot(newSnapshot.getId()); + } + } + + } + + @Test + public void createTemplateFromSnapshot() throws InterruptedException, ExecutionException { + 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(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep); + + 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/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 new file mode 100644 index 00000000000..da4c17b6041 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -0,0 +1,167 @@ +// 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; + +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.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; +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.Matchers; +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.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(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); + + // image.setImageDataStoreId(storeId); + 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); + } + + @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()); + } 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 + public void deleteTemplate() { + TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); + 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/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 new file mode 100644 index 00000000000..70fdb1b5829 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -0,0 +1,433 @@ +/* + * 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.List; +import java.util.UUID; +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; +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.ObjectInDataStoreStateMachine.Event; +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.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; +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.mockito.Matchers; +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.agent.api.Command; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenter.NetworkType; +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.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.HypervisorGuruManager; +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.Volume; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.StoragePoolStatus; +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.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 + VolumeDao 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; + @Inject + HypervisorGuruManager hyGuruMgr; + 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(this.getHypervisor().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(this.getHypervisor()); + host.setClusterId(cluster.getId()); + + host = hostDao.persist(host); + + imageStore = new ImageStoreVO(); + imageStore.setName(imageStoreName); + 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); + } + + 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()); + to.setFormat(ImageFormat.VHD); + to.setSize(100L); + 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) 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(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() { + 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(DataStoreProvider.DEFAULT_PRIMARY); + 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(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000); + ; + 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(); + boolean res = this.volumeService.destroyVolume(newVol.getId()); + Assert.assertTrue(res); + VolumeInfo vol = this.volFactory.getVolume(volume.getId()); + future = this.volumeService.expungeVolumeAsync(vol); + result = future.get(); + Assert.assertTrue(result.isSuccess()); + } catch (InterruptedException e) { + Assert.fail(e.toString()); + } catch (ExecutionException e) { + Assert.fail(e.toString()); + } catch (ConcurrentOperationException e) { + Assert.fail(e.toString()); + } + } + + @Test + 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); + VolumeApiResult result = future.get(); + Assert.assertTrue(result.isSuccess()); + } + + @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() { + 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() 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); + + 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); + + AsyncCallFuture templateResult = this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore); + TemplateApiResult templateApiResult = templateResult.get(); + Assert.assertTrue(templateApiResult.isSuccess()); + } +} 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..4acc8dc7de8 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java @@ -0,0 +1,444 @@ +/* + * 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.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.ObjectInDataStoreStateMachine.Event; +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.VolumeService.VolumeApiResult; +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.mockito.Matchers; +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.DataCenter.NetworkType; +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.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.Volume; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.StoragePoolStatus; +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.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 + VolumeDao 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) 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(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() { + 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(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000); + ; + 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/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..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 @@ -30,30 +30,27 @@ 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; 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.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.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.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.HypervisorHostEndPoint; +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.endpoint.EndPointSelector; -import org.apache.cloudstack.storage.volume.db.VolumeDao2; -import org.apache.cloudstack.storage.volume.db.VolumeVO; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.Assert; @@ -74,61 +71,64 @@ 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.Volume; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; 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.utils.component.ComponentContext; -@ContextConfiguration(locations={"classpath:/storageContext.xml"}) +@ContextConfiguration(locations = { "classpath:/storageContext.xml" }) public class volumeServiceTest extends CloudStackTestNGBase { - //@Inject - //ImageDataStoreProviderManager imageProviderMgr; - @Inject - ImageService imageService; - @Inject - VolumeService volumeService; - @Inject - VMTemplateDao imageDataDao; - @Inject - VolumeDao2 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 - ImageDataFactory imageDataFactory; - @Inject - VolumeDataFactory volumeFactory; - 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(); - /* 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(); @@ -136,59 +136,53 @@ 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); - //primaryStore = createPrimaryDataStore(); - - //CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(UUID.randomUUID().toString()); + 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); - /*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 protected void injectMockito() { if (host == null) { @@ -197,72 +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(HypervisorHostEndPoint.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)); - 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); - - //image.setImageDataStoreId(storeId); - image = imageDataDao.persist(image); - - return image; - } + 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 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; - } - } + // image.setImageDataStoreId(storeId); + image = imageDataDao.persist(image); - //@Test - public void createTemplateTest() { - createTemplate(); - } - - @Test - public void testCreatePrimaryStorage() { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default primary data store provider"); + 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; + } + } + + // @Test + public void createTemplateTest() { + createTemplate(); + } + + @Test + public void testCreatePrimaryStorage() { + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); Map params = new HashMap(); URI uri = null; try { @@ -282,15 +283,15 @@ 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); + this.primaryStore = lifeCycle.initialize(params); ClusterScope scope = new ClusterScope(clusterId, podId, dcId); lifeCycle.attachCluster(this.primaryStore, scope); - } - - private DataStore createImageStore() { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default image data store"); + } + + 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); @@ -301,19 +302,20 @@ public class volumeServiceTest extends CloudStackTestNGBase { DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); DataStore store = lifeCycle.initialize(params); return store; - } - //@Test - public void testcreateImageStore() { - createImageStore(); - } - + } - public DataStore createPrimaryDataStore() { - try { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default primary data store provider"); - Map params = new HashMap(); - URI uri = new URI(this.getPrimaryStorageUrl()); - params.put("url", this.getPrimaryStorageUrl()); + // @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()); params.put("server", uri.getHost()); params.put("path", uri.getPath()); params.put("protocol", Storage.StoragePoolType.NetworkFilesystem); @@ -324,58 +326,59 @@ 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("default 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; - } - } - 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; - } + DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); + DataStore store = lifeCycle.initialize(params); + ClusterScope scope = new ClusterScope(clusterId, podId, dcId); + lifeCycle.attachCluster(store, scope); - @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 { + /* + * 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; + } + } + + 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 { future.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block @@ -384,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 @@ -401,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 @@ -431,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/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/storageContext.xml b/engine/storage/integration-test/test/resource/storageContext.xml index 7c5382d49f9..9f4f102edec 100644 --- a/engine/storage/integration-test/test/resource/storageContext.xml +++ b/engine/storage/integration-test/test/resource/storageContext.xml @@ -21,23 +21,70 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - - - - - - - - - - - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/engine/storage/integration-test/test/resource/testng.xml b/engine/storage/integration-test/test/resource/testng.xml index db32c247d1b..fb4330999f3 100644 --- a/engine/storage/integration-test/test/resource/testng.xml +++ b/engine/storage/integration-test/test/resource/testng.xml @@ -23,12 +23,25 @@ - + - - + + + + + + + + + + + + + + + diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index 270fe47c743..cc561161602 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -47,10 +47,15 @@ org.apache.cloudstack - cloud-engine-api + cloud-secondary-storage ${project.version} + org.apache.cloudstack + cloud-engine-api + ${project.version} + + mysql mysql-connector-java ${cs.mysql.version} diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index 211cdac574e..350a9a9eed6 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -25,6 +25,11 @@ cloud-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 fa7772a979d..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 @@ -21,19 +21,16 @@ package org.apache.cloudstack.storage.snapshot; 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.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; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -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.springframework.stereotype.Component; -import com.cloud.storage.Snapshot; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.utils.exception.CloudRuntimeException; @@ -43,42 +40,38 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { @Inject SnapshotDao snapshotDao; @Inject - ObjectInDataStoreManager objMap; + SnapshotDataStoreDao snapshotStoreDao; @Inject DataStoreManager storeMgr; @Inject VolumeDataFactory volumeFactory; + @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()); - if (obj == null) { - return null; - } - SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); + 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 = objMap.findStore(snapshot.getUuid(), DataObjectType.SNAPSHOT, 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); + 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 37238b72121..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,50 +22,68 @@ 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.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; -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; +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; +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; 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; public class SnapshotObject implements SnapshotInfo { - private static final Logger s_logger = Logger.getLogger(SnapshotObject.class); + private static final Logger s_logger = Logger.getLogger(SnapshotObject.class); private SnapshotVO snapshot; private DataStore store; @Inject - protected SnapshotDao snapshotDao; + protected SnapshotDao snapshotDao; @Inject protected VolumeDao volumeDao; - @Inject protected VolumeDataFactory volFactory; - @Inject protected SnapshotStateMachineManager stateMachineMgr; @Inject - ObjectInDataStoreManager ojbectInStoreMgr; + protected VolumeDataFactory volFactory; + @Inject + protected SnapshotStateMachineManager stateMachineMgr; + @Inject + SnapshotDataFactory snapshotFactory; + @Inject + ObjectInDataStoreManager objectInStoreMgr; + @Inject + SnapshotDataStoreDao snapshotStoreDao; + public SnapshotObject() { - + } - + protected void configure(SnapshotVO snapshot, DataStore store) { - this.snapshot = snapshot; - this.store = 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); - return snapObj; + SnapshotObject snapObj = ComponentContext.inject(SnapshotObject.class); + snapObj.configure(snapshot, store); + return snapObj; } public DataStore getStore() { @@ -74,14 +92,32 @@ public class SnapshotObject implements SnapshotInfo { @Override public SnapshotInfo getParent() { - // TODO Auto-generated method stub - return null; + SnapshotDataStoreVO snapStoreVO = this.snapshotStoreDao.findByStoreSnapshot(this.store.getRole(), + this.store.getId(), this.snapshot.getId()); + if (snapStoreVO == null) { + 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 @@ -91,7 +127,7 @@ public class SnapshotObject implements SnapshotInfo { @Override public long getId() { - return this.snapshot.getId(); + return this.snapshot.getId(); } @Override @@ -106,17 +142,12 @@ public class SnapshotObject implements SnapshotInfo { @Override public Long getSize() { - return this.snapshot.getSize(); + return this.snapshot.getSize(); } @Override public DataObjectType getType() { - return DataObjectType.SNAPSHOT; - } - - @Override - public DiskFormat getFormat() { - return null; + return DataObjectType.SNAPSHOT; } @Override @@ -124,100 +155,180 @@ public class SnapshotObject implements SnapshotInfo { return this.snapshot.getUuid(); } - @Override - public void processEvent( - ObjectInDataStoreStateMachine.Event event) { - try { - ojbectInStoreMgr.update(this, event); - } catch (Exception e) { - s_logger.debug("Failed to update state:" + e.toString()); - throw new CloudRuntimeException("Failed to update state: " + e.toString()); - } - } + @Override + public void processEvent(ObjectInDataStoreStateMachine.Event event) { + try { + objectInStoreMgr.update(this, event); + } catch (Exception e) { + s_logger.debug("Failed to update state:" + e.toString()); + throw new CloudRuntimeException("Failed to update state: " + e.toString()); + } finally { + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { + objectInStoreMgr.delete(this); + } + } + } - @Override - public long getAccountId() { - return this.snapshot.getAccountId(); - } + @Override + public long getAccountId() { + return this.snapshot.getAccountId(); + } - @Override - public long getVolumeId() { - return this.snapshot.getVolumeId(); - } + @Override + public long getVolumeId() { + return this.snapshot.getVolumeId(); + } - @Override - public String getPath() { - return this.snapshot.getPath(); - } - - public void setPath(String path) { - this.snapshot.setPath(path); - } + @Override + public String getPath() { + return this.objectInStoreMgr.findObject(this, getDataStore()).getInstallPath(); + } - @Override - public String getName() { - return this.snapshot.getName(); - } + @Override + public String getName() { + return this.snapshot.getName(); + } - @Override - public Date getCreated() { - return this.snapshot.getCreated(); - } + @Override + public Date getCreated() { + return this.snapshot.getCreated(); + } - @Override - public Type getRecurringType() { - return this.snapshot.getRecurringType(); - } + @Override + public Type getRecurringType() { + return this.snapshot.getRecurringType(); + } - @Override - public State getState() { - return this.snapshot.getState(); - } + @Override + public State getState() { + return this.snapshot.getState(); + } - @Override - public HypervisorType getHypervisorType() { - return this.snapshot.getHypervisorType(); - } + @Override + public HypervisorType getHypervisorType() { + return this.snapshot.getHypervisorType(); + } - @Override - public boolean isRecursive() { - return this.snapshot.isRecursive(); - } + @Override + public boolean isRecursive() { + return this.snapshot.isRecursive(); + } - @Override - public short getsnapshotType() { - return this.snapshot.getsnapshotType(); - } + @Override + public short getsnapshotType() { + return this.snapshot.getsnapshotType(); + } - @Override - public long getDomainId() { - return this.snapshot.getDomainId(); - } - - public void setPrevSnapshotId(Long id) { - this.snapshot.setPrevSnapshotId(id); - } + @Override + public long getDomainId() { + return this.snapshot.getDomainId(); + } - @Override - public Long getDataCenterId() { - return this.snapshot.getDataCenterId(); - } - - public void processEvent(Snapshot.Event event) - throws NoTransitionException { - stateMachineMgr.processEvent(this.snapshot, event); - } + @Override + public Long getDataCenterId() { + return this.snapshot.getDataCenterId(); + } - @Override - public Long getPrevSnapshotId() { - return this.snapshot.getPrevSnapshotId(); - } - - public void setBackupSnapshotId(String id) { - this.snapshot.setBackupSnapshotId(id); - } - - public String getBackupSnapshotId() { - return this.snapshot.getBackupSnapshotId(); - } + public void processEvent(Snapshot.Event event) throws NoTransitionException { + stateMachineMgr.processEvent(this.snapshot, event); + } + + public SnapshotVO getSnapshotVO() { + return this.snapshot; + } + + @Override + public DataTO getTO() { + 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) { + try { + 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.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.snapshotStoreDao.update(snapshotStore.getId(), snapshotStore); + } else { + throw new CloudRuntimeException("Unknown answer: " + answer.getClass()); + } + } catch (RuntimeException ex) { + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { + objectInStoreMgr.delete(this); + } + throw ex; + } + 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.findByStoreSnapshot(this.store.getRole(), this.store.getId(), + this.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.findByStoreSnapshot(this.store.getRole(), this.store.getId(), + this.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.findByStoreSnapshot(this.store.getRole(), this.store.getId(), + this.getId()); + return store.getRefCnt(); + } + return null; + } + + @Override + public ObjectInDataStoreStateMachine.State getStatus() { + return this.objectInStoreMgr.findObject(this, store).getObjectInStoreState(); + } + + @Override + public void addPayload(Object data) { + } + + @Override + public boolean delete() { + if (store != null) { + return store.delete(this); + } + return true; + } } 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..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 @@ -14,43 +14,369 @@ // 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; +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.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.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; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import javax.inject.Inject; +import java.util.concurrent.ExecutionException; + @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 + protected SnapshotDataStoreDao _snapshotStoreDao; - @Override - public SnapshotEntity getSnapshotEntity(long snapshotId) { - // TODO Auto-generated method stub - return null; - } + @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; - @Override - public boolean takeSnapshot(SnapshotInfo snapshot) { - // TODO Auto-generated method stub - return false; - } + static private class CreateSnapshotContext extends AsyncRpcConext { + final SnapshotInfo snapshot; + final AsyncCallFuture future; - @Override - public boolean revertSnapshot(SnapshotInfo snapshot) { - // TODO Auto-generated method stub - return false; - } + public CreateSnapshotContext(AsyncCompletionCallback callback, VolumeInfo volume, SnapshotInfo snapshot, + AsyncCallFuture future) { + super(callback); + this.snapshot = snapshot; + this.future = future; + } + } - @Override - public boolean deleteSnapshot(SnapshotInfo snapshot) { - // TODO Auto-generated method stub - return false; - } - - + 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; + 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; + } + + 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; + } + + @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 { + 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 { + 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; + } 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()); + } + } + + @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); + + DataStore imageStore = this.findSnapshotImageStore(snapshot); + if (imageStore == null) { + throw new CloudRuntimeException("can not find an image stores"); + } + + 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(); + 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; + } + + 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; + } + + + 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); + + 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; + + } + + @Override + public boolean revertSnapshot(SnapshotInfo snapshot) { + 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..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/SnapshotStateMachineManagerImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java index aa1cf684d7a..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,24 +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.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/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java similarity index 57% rename from engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java rename to engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java index f3e5c4aea50..1b579227f84 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java @@ -11,17 +11,28 @@ // 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.snapshot; -import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import javax.inject.Inject; -public interface SnapshotService { - public SnapshotEntity getSnapshotEntity(long snapshotId); - public boolean takeSnapshot(SnapshotInfo snapshot); - public boolean revertSnapshot(SnapshotInfo snapshot); - public boolean deleteSnapshot(SnapshotInfo snapshot); +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; + + @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..92af8c2b071 --- /dev/null +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -0,0 +1,204 @@ +// 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; + +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.SnapshotDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +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.storage.DataStoreRole; +import com.cloud.storage.Snapshot; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.dao.SnapshotDao; +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 + 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()); + + 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; + + 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); + + 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); + } + + 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 { + 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(); + return this.backupSnapshot(snapshot); + } + + @Override + public boolean canHandle(Snapshot snapshot) { + return true; + } +} 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 b05b803623f..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/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 4aba3d919b5..00000000000 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java +++ /dev/null @@ -1,613 +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.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.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; -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.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; -import com.cloud.resource.ResourceManager; -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.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; -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.getImageStores(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.getUuid(), 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.Error.equals(snapshot.getState())) { - _snapshotDao.remove(snapshotId); - return true; - } - - 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/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/HypervisorHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java deleted file mode 100644 index 6c49b1a0e9e..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.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 org.apache.cloudstack.storage; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -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 HypervisorHostEndPoint implements EndPoint { - private static final Logger s_logger = Logger.getLogger(HypervisorHostEndPoint.class); - private long hostId; - private String hostAddress; - @Inject - AgentManager agentMgr; - @Inject - HostEndpointRpcServer rpcServer; - - protected HypervisorHostEndPoint() { - - } - - private void configure(long hostId, String hostAddress) { - this.hostId = hostId; - this.hostAddress = hostAddress; - } - - public static HypervisorHostEndPoint getHypervisorHostEndPoint(long hostId, String hostAddress) { - HypervisorHostEndPoint ep = ComponentContext.inject(HypervisorHostEndPoint.class); - ep.configure(hostId, hostAddress); - return ep; - } - - public String getHostAddr() { - return this.hostAddress; - } - - public long getId() { - return this.hostId; - } - - @Override - public Answer sendMessage(Command cmd) { - return rpcServer.sendCommand(this, cmd); - } - - @Override - public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { - rpcServer.sendCommandAsync(this, cmd, callback); - } -} 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 060b490e6a8..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) { - this.rpcProvider = rpcProvider; - rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this)); - } - - @PostConstruct - public void Initialize() { - rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this)); - } - - @Override - public void sendCommandAsync(HypervisorHostEndPoint 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(HypervisorHostEndPoint 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 new file mode 100644 index 00000000000..18fcd7178d2 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -0,0 +1,101 @@ +// 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; +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.CopyCommand; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.resource.LocalNfsSecondaryStorageResource; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.resource.ServerResource; +import com.cloud.utils.net.NetUtils; + +public class LocalHostEndpoint implements EndPoint { + 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; + } + + @Override + public String getHostAddr() { + return "127.0.0.0"; + } + + @Override + public String getPublicAddr() { + String hostIp = NetUtils.getDefaultHostIp(); + if (hostIp != null) + return hostIp; + else + return "127.0.0.0"; + } + + @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()); + } + + 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) { + 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 new file mode 100644 index 00000000000..cd64ab2457c --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -0,0 +1,178 @@ +/* + * 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; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +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.AgentControlAnswer; +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.agent.manager.Commands; +import com.cloud.exception.AgentUnavailableException; +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; + +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 + protected HypervisorGuruManager _hvGuruMgr; + private ScheduledExecutorService executor; + + public RemoteHostEndPoint() { + executor = Executors.newScheduledThreadPool(10); + } + + 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, String publicAddress) { + RemoteHostEndPoint ep = ComponentContext.inject(RemoteHostEndPoint.class); + ep.configure(hostId, hostAddress, publicAddress); + return ep; + } + + @Override + public String getHostAddr() { + return this.hostAddress; + } + + @Override + public String getPublicAddr() { + return this.publicAddress; + } + + @Override + public long getId() { + return this.hostId; + } + + @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); + } + + private class CmdRunner implements Listener, Runnable { + final AsyncCompletionCallback callback; + Answer answer; + + public CmdRunner(AsyncCompletionCallback callback) { + this.callback = callback; + } + + @Override + public boolean processAnswers(long agentId, long seq, Answer[] answers) { + this.answer = answers[0]; + executor.schedule(this, 10, TimeUnit.SECONDS); + return true; + } + + @Override + public boolean processCommands(long agentId, long seq, Command[] commands) { + // TODO Auto-generated method stub + return false; + } + + @Override + public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + // TODO Auto-generated method stub + + } + + @Override + public boolean processDisconnect(long agentId, Status state) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isRecurring() { + // TODO Auto-generated method stub + return false; + } + + @Override + public int getTimeout() { + // TODO Auto-generated method stub + return -1; + } + + @Override + public boolean processTimeout(long agentId, long seq) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void run() { + callback.complete(answer); + } + } + + @Override + public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { + try { + 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 f95993985ef..dd6a6a2781b 100755 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java @@ -27,10 +27,11 @@ import java.util.Random; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.log4j.Logger; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; @@ -49,18 +50,23 @@ import com.cloud.user.Account; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.AdapterBase; import com.cloud.vm.DiskProfile; -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); + @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; @@ -75,7 +81,8 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement 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; @@ -91,30 +98,36 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement 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) { + 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); } @@ -123,51 +136,57 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement 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) { + protected List reOrder(List pools, VirtualMachineProfile vmProfile, DeploymentPlan plan) { Account account = null; - if(vmProfile.getVirtualMachine() != null){ + if (vmProfile.getVirtualMachine() != null) { account = vmProfile.getOwner(); } - if(_allocationAlgorithm.equals("random") || _allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) { + 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")){ + } else if (_allocationAlgorithm.equals("userdispersing")) { pools = reorderPoolsByNumberOfVolumes(plan, pools, account); } return pools; } - protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, - DeploymentPlan plan) { + 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()); + 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 (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"); + return false; + } + Long clusterId = pool.getClusterId(); ClusterVO cluster = _clusterDao.findById(clusterId); if (!(cluster.getHypervisorType() == dskCh.getHypervisorType())) { @@ -177,7 +196,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement return false; } - // check capacity + // check capacity Volume volume = _volumeDao.findById(dskCh.getVolumeId()); List requestVolumes = new ArrayList(); requestVolumes.add(volume); 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 4288e5e16f7..146c2e22495 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java @@ -25,22 +25,22 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; + import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.offering.ServiceOffering; import com.cloud.storage.StoragePool; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.vm.DiskProfile; -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"; @@ -58,9 +58,10 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat 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{ + 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); } @@ -75,17 +76,18 @@ 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){ + for (StoragePoolVO pool : pools) { + if (suitablePools.size() == returnUpTo) { break; } - StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + StoragePool pol = (StoragePool) dataStoreMgr.getPrimaryDataStore(pool.getId()); if (filter(avoid, pol, dskCh, plan)) { suitablePools.add(pol); } else { @@ -94,7 +96,7 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat } 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; 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 78cc1b71d54..cae4d2a41ee 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java @@ -23,9 +23,10 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.log4j.Logger; +import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; + import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; @@ -33,17 +34,18 @@ import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.utils.component.ComponentContext; 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 @@ -65,7 +67,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 +83,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 6d3b22d7afd..7198a28f3b5 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java @@ -25,11 +25,12 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; + import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.deploy.DeploymentPlan; @@ -41,7 +42,6 @@ import com.cloud.storage.Volume; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.NumbersUtil; import com.cloud.vm.DiskProfile; -import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @@ -78,10 +78,10 @@ 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()); + StoragePool pol = (StoragePool) 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); @@ -95,12 +95,13 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator { } } } else { - List availablePools = _storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), dskCh.getTags()); + 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()); + StoragePool pol = (StoragePool) dataStoreMgr.getPrimaryDataStore(pool.getId()); if (filter(avoid, pol, dskCh, plan)) { suitablePools.add(pol); } else { 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 b9a88bbe37c..c3c901523d6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java @@ -31,17 +31,18 @@ import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.storage.StoragePool; 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; 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 9da3475a1ce..e916a5c7971 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java @@ -21,11 +21,12 @@ import java.util.List; import javax.inject.Inject; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + 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; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; @@ -33,18 +34,18 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.vm.DiskProfile; -import com.cloud.vm.VirtualMachine; 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; + @Inject + PrimaryDataStoreDao _storagePoolDao; + @Inject + DataStoreManager dataStoreMgr; @Override - protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, - DeploymentPlan plan) { + protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, DeploymentPlan plan) { Volume volume = _volumeDao.findById(dskCh.getVolumeId()); List requestVolumes = new ArrayList(); requestVolumes.add(volume); @@ -52,8 +53,7 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { } @Override - protected List select(DiskProfile dskCh, - VirtualMachineProfile vmProfile, + 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(); @@ -80,7 +80,7 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { if (suitablePools.size() == returnUpTo) { break; } - StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(storage.getId()); + StoragePool pol = (StoragePool) dataStoreMgr.getPrimaryDataStore(storage.getId()); if (filter(avoid, pol, dskCh, plan)) { suitablePools.add(pol); } else { 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 20bf0545dc9..ef215284ddd 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java @@ -18,20 +18,25 @@ */ 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); + 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 9d1afbeacad..6e97e6f9f74 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java @@ -20,9 +20,9 @@ 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; 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 +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.motion.DataMotionService; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -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 a2fd08d1e8f..b92f92f655e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -25,50 +25,73 @@ 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.storage.image.datastore.ImageDataStoreManager; +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; +import edu.emory.mathcs.backport.java.util.Collections; + @Component public class DataStoreManagerImpl implements DataStoreManager { @Inject PrimaryDataStoreProviderManager primaryStorMgr; @Inject - ImageDataStoreManager 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); + } else if (role == DataStoreRole.ImageCache) { + return imageDataStoreMgr.getImageStore(storeId); } 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) { return primaryStorMgr.getPrimaryDataStore(uuid); } else if (role == DataStoreRole.Image) { - return imageDataStoreMgr.getImageDataStore(uuid); + return imageDataStoreMgr.getImageStore(uuid); } throw new CloudRuntimeException("un recognized type" + role); } + @Override - public List getImageStores(Scope scope) { - return imageDataStoreMgr.getList(); + public List getImageStoresByScope(ZoneScope scope) { + return imageDataStoreMgr.listImageStoresByScope(scope); } + + @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 DataStore getPrimaryDataStore(long storeId) { return primaryStorMgr.getPrimaryDataStore(storeId); } + @Override + public List getImageCacheStores(Scope 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 d170f5c707a..b72d07b2d88 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -18,19 +18,25 @@ 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.DataStoreRole; 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; 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(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); + + 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 87ba1d216c5..4b3d4a622d5 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -20,132 +20,235 @@ 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.DataStoreRole; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +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.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; +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; +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.VMTemplateHostDao; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VolumeHostDao; -import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.template.TemplateConstants; 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 - ImageDataFactory imageFactory; + TemplateDataFactory imageFactory; @Inject DataStoreManager storeMgr; @Inject VolumeDataFactory volumeFactory; @Inject - ObjectInDataStoreDao objectDataStoreDao; + TemplateDataStoreDao templateDataStoreDao; @Inject - VolumeHostDao volumeHostDao; + SnapshotDataStoreDao snapshotDataStoreDao; @Inject - VMTemplateHostDao templateHostDao; + VolumeDataStoreDao volumeDataStoreDao; @Inject VMTemplatePoolDao templatePoolDao; @Inject SnapshotDataFactory snapshotFactory; + @Inject + ObjectInDataStoreDao objInStoreDao; + @Inject + VMTemplateDao templateDao; + @Inject + SnapshotDao snapshotDao; + @Inject + VolumeDao volumeDao; protected StateMachine2 stateMachines; public ObjectInDataStoreManagerImpl() { stateMachines = new StateMachine2(); - stateMachines.addTransition(State.Allocated, Event.CreateRequested, - 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.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, - 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 (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 if (obj.getType() == DataObjectType.SNAPSHOT) { + SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); + ss.setSnapshotId(obj.getId()); + ss.setDataStoreId(dataStore.getId()); + ss.setRole(dataStore.getRole()); + ss.setState(ObjectInDataStoreStateMachine.State.Allocated); + ss = snapshotDataStoreDao.persist(ss); + } } 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.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 + } + ts.setInstallPath(installPath); + ts.setState(ObjectInDataStoreStateMachine.State.Allocated); + 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() + "/" + snapshot.getVolumeId()); + ss.setState(ObjectInDataStoreStateMachine.State.Allocated); + ss = snapshotDataStoreDao.persist(ss); + break; + case VOLUME: + 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.setState(ObjectInDataStoreStateMachine.State.Allocated); + 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 { - DataObjectInStore obj = this.findObject(data, data.getDataStore()); - if (obj == null) { - throw new CloudRuntimeException( - "can't find mapping in ObjectInDataStore table for: " - + data); - } - - if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) { - try { - this.stateMachines.transitTo(obj, event, null, - templatePoolDao); - } catch (NoTransitionException e) { - if (event == Event.CreateOnlyRequested || event == Event.OperationSuccessed) { - s_logger.debug("allow muliple create requests"); + 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 { - throw e; + s_logger.warn("Template " + objId + " is not found on storage pool " + dataStore.getId() + + ", so no need to delete"); + return true; } } } else { - this.stateMachines.transitTo(obj, event, null, objectDataStoreDao); + // 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.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"); + 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 { + DataObjectInStore obj = this.findObject(data, data.getDataStore()); + if (obj == null) { + 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()) { + 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) { + + 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()); } return true; } @@ -155,58 +258,65 @@ 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(); + if (role == DataStoreRole.Image || role == DataStoreRole.ImageCache) { + 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); + } 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); } + return vo; + } - + @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().getObjectType(), Op.EQ, type); - ObjectInDataStoreVO vo = sc.find(); + DataObjectInStore vo = null; + switch (type) { + case TEMPLATE: + vo = templateDataStoreDao.findByTemplate(objId, role); + break; + case SNAPSHOT: + vo = snapshotDataStoreDao.findBySnapshot(objId, role); + break; + case VOLUME: + vo = volumeDataStoreDao.findByVolume(objId); + break; + } if (vo != null) { - store = this.storeMgr.getDataStore(vo.getDataStoreUuid(), vo.getDataStoreRole()); + store = this.storeMgr.getDataStore(vo.getDataStoreId(), role); } } return store; 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..e861910116a 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; } @@ -171,7 +170,7 @@ public class PrimaryDataStoreEntityImpl implements StorageEntity { } @Override - public long getAvailableBytes() { + public long getUsedBytes() { // TODO Auto-generated method stub return 0; } @@ -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 40a65dcf07f..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 @@ -31,11 +31,10 @@ 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.PrimaryDataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; -import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao; +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; @@ -44,30 +43,24 @@ 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; - @Inject - DataStoreProviderDao providerDao; protected Map providerMap = new HashMap(); @Inject PrimaryDataStoreProviderManager primaryDataStoreProviderMgr; + @Inject + ImageStoreProviderManager imageDataStoreProviderMgr; + @Override public DataStoreProvider getDataStoreProvider(String name) { 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()) { - if (provider instanceof PrimaryDataStoreProvider) { + if (provider.getTypes().contains(DataStoreProviderType.PRIMARY)) { StorageProviderResponse response = new StorageProviderResponse(); response.setName(provider.getName()); response.setType(DataStoreProvider.DataStoreProviderType.PRIMARY.toString()); @@ -76,11 +69,11 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } return providers; } - + public List getImageDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { - if (provider instanceof ImageDataStoreProvider) { + if (provider.getTypes().contains(DataStoreProviderType.IMAGE)) { StorageProviderResponse response = new StorageProviderResponse(); response.setName(provider.getName()); response.setType(DataStoreProvider.DataStoreProviderType.IMAGE.toString()); @@ -90,20 +83,33 @@ 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) - 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; } - + s_logger.debug("registering data store provider:" + provider.getName()); - + providerMap.put(providerName, provider); try { boolean registrationResult = provider.configure(copyParams); @@ -112,24 +118,39 @@ 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.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()); } - } catch(Exception e) { + } catch (Exception e) { s_logger.debug("configure provider failed", e); providerMap.remove(providerName); + return false; } } - + return true; } @Override public DataStoreProvider getDefaultPrimaryDataStoreProvider() { - return this.getDataStoreProvider("ancient primary data store provider"); + return this.getDataStoreProvider(DataStoreProvider.DEFAULT_PRIMARY); + } + + @Override + public DataStoreProvider getDefaultImageDataStoreProvider() { + return this.getDataStoreProvider(DataStoreProvider.NFS_IMAGE); + } + + @Override + public DataStoreProvider getDefaultCacheDataStoreProvider() { + return this.getDataStoreProvider(DataStoreProvider.NFS_IMAGE); } @Override @@ -141,6 +162,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/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 0fbcbb1f956..df9c83641f6 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,11 @@ 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.DataStoreRole; 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; import com.cloud.utils.db.GenericDaoBase; @@ -46,16 +47,16 @@ public class ObjectInDataStoreVO implements StateObject 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(), + host.getPublicIpAddress()); + } + + 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(); + 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 - //TODO: add code to handle in case ssvm is there - return findEndpointForPrimaryStorage(store); - }else { + // 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 { throw new CloudRuntimeException("not implemented yet"); } - } - + @Override public List selectAll(DataStore store) { List endPoints = new ArrayList(); if (store.getScope().getScopeType() == ScopeType.HOST) { HostVO host = hostDao.findById(store.getScope().getScopeId()); - endPoints.add(HypervisorHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress())); + 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(HypervisorHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress())); + endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), + host.getPublicIpAddress())); } - + } else { throw new CloudRuntimeException("shouldn't use it for other scope"); } 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..93b0c2b373d --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java @@ -0,0 +1,216 @@ +/* + * 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 DataTO getTO(DataObject data) { + 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) { + } + + @Override + public boolean canCopy(DataObject srcData, DataObject destData) { + return false; + } + + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + } +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java new file mode 100644 index 00000000000..85a42ff7c0c --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.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.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/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java index 4d162bbdd09..138f57c334e 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() { @@ -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,6 +101,10 @@ public class TemplateEntityImpl implements TemplateEntity { return null; } + @Override + public Boolean isDynamicallyScalable() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } @Override public void addDetail(String name, String value) { 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 3f1632cf13c..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.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.image.datastore; - -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.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 = 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/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java new file mode 100644 index 00000000000..a2d61f91fbe --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -0,0 +1,118 @@ +/* + * 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 java.util.UUID; + +import javax.inject.Inject; + +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.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.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) params.get("role")); + 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.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.setName(store.getUuid()); + } + store.setRole((DataStoreRole) params.get("role")); + 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/ImageDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java similarity index 60% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreManager.java rename to engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java index b6d84cdcef2..be66cc51401 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java @@ -21,11 +21,22 @@ 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.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.image.ImageStoreDriver; -public interface ImageDataStoreManager { - ImageDataStore getImageDataStore(long dataStoreId); - ImageDataStore getImageDataStore(String uuid); - List getList(); - boolean registerDriver(String uuid, ImageDataStoreDriver driver); +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/ImageDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreDao.java deleted file mode 100644 index d7358be9140..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreDao.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 ImageDataStoreDao extends GenericDao { - public ImageDataStoreVO findByName(String name); -} 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/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java new file mode 100644 index 00000000000..acbbc7d74a8 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -0,0 +1,107 @@ +/* + * 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 java.util.List; +import java.util.Map; + +import javax.naming.ConfigurationException; + +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.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; +import com.cloud.utils.db.SearchCriteria; + +@Component +public class ImageStoreDaoImpl extends GenericDaoBase implements ImageStoreDao { + private SearchBuilder nameSearch; + private SearchBuilder providerSearch; + + @Override + 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.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; + } + + @Override + public ImageStoreVO findByName(String name) { + SearchCriteria sc = nameSearch.create(); + sc.setParameters("name", name); + return findOneBy(sc); + } + + @Override + public List findByProvider(String provider) { + SearchCriteria sc = providerSearch.create(); + sc.setParameters("providerName", provider); + sc.setParameters("role", DataStoreRole.Image); + return listBy(sc); + } + + @Override + public List findByScope(ZoneScope scope) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.Image); + 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); + } + + @Override + public List findImageCacheByScope(ZoneScope scope) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.ImageCache); + if (scope.getScopeId() != null) { + sc.addAnd("scope", SearchCriteria.Op.EQ, ScopeType.ZONE); + sc.addAnd("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); + } + return listBy(sc); + } + + @Override + public List listImageStores() { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.Image); + 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 new file mode 100644 index 00000000000..ad52042bc7c --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java @@ -0,0 +1,88 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.storage.image.db; + +import java.util.HashMap; +import java.util.List; +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.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) +public class ImageStoreDetailsDaoImpl extends GenericDaoBase implements ImageStoreDetailsDao { + + protected final SearchBuilder storeSearch; + + protected ImageStoreDetailsDaoImpl() { + 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()) { + ImageStoreDetailVO detail = new ImageStoreDetailVO(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 (ImageStoreDetailVO detail : details) { + detailsMap.put(detail.getName(), detail.getValue()); + } + + return detailsMap; + } + + @Override + public void deleteDetails(long storeId) { + SearchCriteria 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/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java new file mode 100644 index 00000000000..a198004370d --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -0,0 +1,168 @@ +// 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 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; +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.DataStoreRole; +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 SnapshotDataStoreDao { + private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class); + private SearchBuilder updateStateSearch; + private SearchBuilder storeSearch; + private SearchBuilder destroyedSearch; + private SearchBuilder snapshotSearch; + private SearchBuilder storeSnapshotSearch; + + @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("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ); + storeSearch.done(); + + destroyedSearch = createSearchBuilder(); + destroyedSearch.and("store_id", destroyedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + destroyedSearch.and("store_role", destroyedSearch.entity().getRole(), SearchCriteria.Op.EQ); + destroyedSearch.and("state", destroyedSearch.entity().getState(), SearchCriteria.Op.EQ); + destroyedSearch.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(); + + snapshotSearch = createSearchBuilder(); + snapshotSearch.and("snapshot_id", snapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); + snapshotSearch.and("store_role", snapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); + snapshotSearch.done(); + + storeSnapshotSearch = createSearchBuilder(); + storeSnapshotSearch.and("snapshot_id", storeSnapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ); + storeSnapshotSearch.and("store_id", storeSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSnapshotSearch.and("store_role", storeSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ); + storeSnapshotSearch.done(); + + return true; + } + + @Override + public boolean updateState(State currentState, Event event, State nextState, DataObjectInStore vo, Object data) { + SnapshotDataStoreVO dataObj = (SnapshotDataStoreVO) vo; + 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()) { + SnapshotDataStoreVO 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; + } + + @Override + public List listByStoreId(long id, DataStoreRole role) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("store_role", role); + return listBy(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(); + } + + @Override + public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId) { + SearchCriteria sc = storeSnapshotSearch.create(); + sc.setParameters("store_id", storeId); + sc.setParameters("snapshot_id", snapshotId); + sc.setParameters("store_role", role); + return findOneIncludingRemovedBy(sc); + } + + @Override + public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role) { + SearchCriteria sc = snapshotSearch.create(); + sc.setParameters("snapshot_id", snapshotId); + sc.setParameters("store_role", role); + return findOneBy(sc); + } + + @Override + public List 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/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java new file mode 100644 index 00000000000..362f7a6aa96 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -0,0 +1,325 @@ +// 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 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.DataStoreRole; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +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; + +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); + private SearchBuilder updateStateSearch; + private SearchBuilder storeSearch; + private SearchBuilder templateSearch; + private SearchBuilder templateRoleSearch; + private SearchBuilder storeTemplateSearch; + private SearchBuilder storeTemplateStateSearch; + private SearchBuilder storeTemplateDownloadStatusSearch; + + @Inject + private DataStoreManager _storeMgr; + + @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(); + + templateSearch = createSearchBuilder(); + templateSearch.and("template_id", templateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + templateSearch.and("destroyed", templateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + templateSearch.done(); + + templateRoleSearch = createSearchBuilder(); + templateRoleSearch.and("template_id", templateRoleSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + templateRoleSearch.and("store_role", templateRoleSearch.entity().getDataStoreRole(), SearchCriteria.Op.EQ); + templateRoleSearch.and("destroyed", templateRoleSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + templateRoleSearch.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(); + + storeTemplateSearch = createSearchBuilder(); + storeTemplateSearch.and("template_id", storeTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + storeTemplateSearch.and("store_id", storeTemplateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeTemplateSearch.and("destroyed", storeTemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + storeTemplateSearch.done(); + + storeTemplateStateSearch = createSearchBuilder(); + storeTemplateStateSearch.and("template_id", storeTemplateStateSearch.entity().getTemplateId(), + SearchCriteria.Op.EQ); + storeTemplateStateSearch.and("store_id", storeTemplateStateSearch.entity().getDataStoreId(), + SearchCriteria.Op.EQ); + storeTemplateStateSearch.and("states", storeTemplateStateSearch.entity().getState(), SearchCriteria.Op.IN); + storeTemplateStateSearch.and("destroyed", storeTemplateStateSearch.entity().getDestroyed(), + SearchCriteria.Op.EQ); + storeTemplateStateSearch.done(); + + storeTemplateDownloadStatusSearch = createSearchBuilder(); + storeTemplateDownloadStatusSearch.and("template_id", + storeTemplateDownloadStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + storeTemplateDownloadStatusSearch.and("store_id", storeTemplateDownloadStatusSearch.entity().getDataStoreId(), + SearchCriteria.Op.EQ); + storeTemplateDownloadStatusSearch.and("downloadState", storeTemplateDownloadStatusSearch.entity() + .getDownloadState(), SearchCriteria.Op.IN); + storeTemplateDownloadStatusSearch.and("destroyed", storeTemplateDownloadStatusSearch.entity().getDestroyed(), + SearchCriteria.Op.EQ); + storeTemplateDownloadStatusSearch.done(); + + storeTemplateSearch = createSearchBuilder(); + storeTemplateSearch.and("store_id", storeTemplateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeTemplateSearch.and("template_id", storeTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + storeTemplateSearch.and("destroyed", storeTemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + storeTemplateSearch.done(); + + return true; + } + + @Override + public boolean updateState(State currentState, Event event, State nextState, DataObjectInStore vo, Object data) { + TemplateDataStoreVO dataObj = (TemplateDataStoreVO) vo; + 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()); + if (nextState == State.Destroyed) { + builder.set(dataObj, "destroyed", true); + } + + 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; + } + + @Override + public List listByStoreId(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", false); + return listIncludingRemovedBy(sc); + } + + @Override + public List 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(); + sc.setParameters("store_id", id); + Transaction txn = Transaction.currentTxn(); + txn.start(); + remove(sc); + txn.commit(); + } + + @Override + public void deletePrimaryRecordsForTemplate(long templateId) { + SearchCriteria 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) { + 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); + } + + @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("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) { + 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(); + sc.setParameters("store_id", storeId); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + return findOneIncludingRemovedBy(sc); + } + + @Override + public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId, boolean lock) { + SearchCriteria 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, DataStoreRole role) { + SearchCriteria sc = templateRoleSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("store_role", role); + 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); + } + + @Override + public TemplateDataStoreVO findByTemplateZone(long templateId, Long zoneId, DataStoreRole role) { + // get all elgible image stores + List 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/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java new file mode 100644 index 00000000000..56020720914 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -0,0 +1,172 @@ +// 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 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.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; + +@Component +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 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(); + + 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); + 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, DataObjectInStore vo, Object data) { + VolumeDataStoreVO dataObj = (VolumeDataStoreVO) vo; + 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()); + if (nextState == State.Destroyed) { + builder.set(dataObj, "destroyed", true); + } + + 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; + } + + @Override + public List listByStoreId(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(); + } + + @Override + public VolumeDataStoreVO findByVolume(long volumeId) { + SearchCriteria 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); + } + + @Override + public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId, boolean lock) { + SearchCriteria 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/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java b/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java index 908d6d52c20..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 @@ -18,13 +18,13 @@ */ 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.db.ObjectInDataStoreVO; -import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; +import org.apache.cloudstack.storage.command.CommandResult; 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/motion/AncientDataMotionStrategy.java b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java deleted file mode 100644 index a6880c3f548..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ /dev/null @@ -1,806 +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.motion; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -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.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.SnapshotInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BackupSnapshotAnswer; -import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; -import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; -import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; -import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.UpgradeSnapshotCommand; -import com.cloud.agent.api.storage.CopyVolumeAnswer; -import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.MigrateVolumeAnswer; -import com.cloud.agent.api.storage.MigrateVolumeCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; -import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; -import com.cloud.agent.api.to.S3TO; -import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.agent.api.to.SwiftTO; -import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.configuration.Config; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.StorageUnavailableException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeManager; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; -import com.cloud.storage.s3.S3Manager; -import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.storage.swift.SwiftManager; -import com.cloud.template.TemplateManager; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.DiskProfile; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.dao.VMInstanceDao; - -@Component -public class AncientDataMotionStrategy implements DataMotionStrategy { - private static final Logger s_logger = Logger - .getLogger(AncientDataMotionStrategy.class); - @Inject - TemplateManager templateMgr; - @Inject - VolumeHostDao volumeHostDao; - @Inject - HostDao hostDao; - @Inject - ConfigurationDao configDao; - @Inject - StorageManager storageMgr; - @Inject - AgentManager agentMgr; - @Inject - VolumeDao volDao; - @Inject - VMInstanceDao instanceDao; - @Inject - VMTemplateDao templateDao; - @Inject - SnapshotManager snapshotMgr; - @Inject - SnapshotDao snapshotDao; - @Inject - PrimaryDataStoreDao primaryDataStoreDao; - @Inject - DataStoreManager dataStoreMgr; - @Inject - VMTemplateHostDao templateHostDao; - @Inject DiskOfferingDao diskOfferingDao; - @Inject VMTemplatePoolDao templatePoolDao; - @Inject - VolumeManager volumeMgr; - @Inject - private SwiftManager _swiftMgr; - @Inject - private S3Manager _s3Mgr; - - @Override - public boolean canHandle(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub - return true; - } - - @Override - public boolean canHandle(Map volumeMap, Host srcHost, Host destHost) { - return false; - } - - @DB - protected Answer copyVolumeFromImage(DataObject srcData, DataObject destData) { - String value = configDao.getValue(Config.RecreateSystemVmEnabled.key()); - int _copyvolumewait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - - VolumeHostVO volumeHostVO = volumeHostDao.findByVolumeId(srcData - .getId()); - HostVO secStorage = hostDao.findById(volumeHostVO.getHostId()); - String secondaryStorageURL = secStorage.getStorageUrl(); - String[] volumePath = volumeHostVO.getInstallPath().split("/"); - String volumeUUID = volumePath[volumePath.length - 1].split("\\.")[0]; - StoragePool destPool = (StoragePool) destData.getDataStore(); - CopyVolumeCommand cvCmd = new CopyVolumeCommand(srcData.getId(), - volumeUUID, destPool, secondaryStorageURL, false, - _copyvolumewait); - CopyVolumeAnswer cvAnswer = null; - String errMsg = null; - try { - cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool, - cvCmd); - } catch (StorageUnavailableException e1) { - s_logger.debug("Failed to copy volume " + srcData.getId() + " to " - + destData.getId(), e1); - errMsg = e1.toString(); - } - - if (cvAnswer == null || !cvAnswer.getResult()) { - errMsg = cvAnswer.getDetails(); - } - - VolumeVO vol = this.volDao.findById(destData.getId()); - Transaction txn = Transaction.currentTxn(); - txn.start(); - vol.setPath(cvAnswer.getVolumePath()); - vol.setFolder(destPool.getPath()); - vol.setPodId(destPool.getPodId()); - vol.setPoolId(destPool.getId()); - vol.setPodId(destPool.getPodId()); - - this.volDao.update(vol.getId(), vol); - volumeHostDao.remove(volumeHostVO.getId()); - txn.commit(); - return cvAnswer; - } - - private Answer copyTemplate(DataObject srcData, DataObject destData) { - VMTemplateVO template = this.templateDao.findById(srcData.getId()); - templateMgr.prepareTemplateForCreate(template, - (StoragePool) destData.getDataStore()); - return null; - } - - protected Answer copyFromSnapshot(DataObject snapObj, DataObject volObj) { - SnapshotVO snapshot = this.snapshotDao.findById(snapObj.getId()); - StoragePool pool = (StoragePool) volObj.getDataStore(); - String vdiUUID = null; - Long snapshotId = snapshot.getId(); - Long volumeId = snapshot.getVolumeId(); - Long dcId = snapshot.getDataCenterId(); - String secondaryStoragePoolUrl = this.snapshotMgr - .getSecondaryStorageURL(snapshot); - long accountId = snapshot.getAccountId(); - - String backedUpSnapshotUuid = snapshot.getBackupSnapshotId(); - snapshot = snapshotDao.findById(snapshotId); - if (snapshot.getVersion().trim().equals("2.1")) { - VolumeVO volume = this.volDao.findByIdIncludingRemoved(volumeId); - if (volume == null) { - throw new CloudRuntimeException("failed to upgrade snapshot " - + snapshotId + " due to unable to find orignal volume:" - + volumeId + ", try it later "); - } - if (volume.getTemplateId() == null) { - snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2"); - } else { - VMTemplateVO template = templateDao - .findByIdIncludingRemoved(volume.getTemplateId()); - if (template == null) { - throw new CloudRuntimeException( - "failed to upgrade snapshot " - + snapshotId - + " due to unalbe to find orignal template :" - + volume.getTemplateId() - + ", try it later "); - } - Long templateId = template.getId(); - Long tmpltAccountId = template.getAccountId(); - if (!snapshotDao.lockInLockTable(snapshotId.toString(), 10)) { - throw new CloudRuntimeException( - "failed to upgrade snapshot " - + snapshotId - + " due to this snapshot is being used, try it later "); - } - UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null, - secondaryStoragePoolUrl, dcId, accountId, volumeId, - templateId, tmpltAccountId, null, - snapshot.getBackupSnapshotId(), snapshot.getName(), - "2.1"); - Answer answer = null; - try { - answer = this.storageMgr.sendToPool(pool, cmd); - } catch (StorageUnavailableException e) { - } finally { - snapshotDao.unlockFromLockTable(snapshotId.toString()); - } - if ((answer != null) && answer.getResult()) { - snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2"); - } else { - throw new CloudRuntimeException("Unable to upgrade snapshot from 2.1 to 2.2 for " - + snapshot.getId()); - } - } - } - String basicErrMsg = "Failed to create volume from " - + snapshot.getName() + " on pool " + pool; - - try { - if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) { - snapshotMgr.downloadSnapshotsFromSwift(snapshot); - } else if (snapshot.getS3Id() != null && snapshot.getS3Id() != 0) { - snapshotMgr.downloadSnapshotsFromS3(snapshot); - } - String value = configDao - .getValue(Config.CreateVolumeFromSnapshotWait.toString()); - int _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CreateVolumeFromSnapshotWait - .getDefaultValue())); - CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand( - pool, secondaryStoragePoolUrl, dcId, accountId, volumeId, - backedUpSnapshotUuid, snapshot.getName(), - _createVolumeFromSnapshotWait); - CreateVolumeFromSnapshotAnswer answer; - if (!snapshotDao.lockInLockTable(snapshotId.toString(), 10)) { - throw new CloudRuntimeException("failed to create volume from " - + snapshotId - + " due to this snapshot is being used, try it later "); - } - answer = (CreateVolumeFromSnapshotAnswer) this.storageMgr - .sendToPool(pool, createVolumeFromSnapshotCommand); - if (answer != null && answer.getResult()) { - vdiUUID = answer.getVdi(); - VolumeVO vol = this.volDao.findById(volObj.getId()); - vol.setPath(vdiUUID); - this.volDao.update(vol.getId(), vol); - return null; - } else { - s_logger.error(basicErrMsg + " due to " - + ((answer == null) ? "null" : answer.getDetails())); - throw new CloudRuntimeException(basicErrMsg); - } - } catch (StorageUnavailableException e) { - s_logger.error(basicErrMsg, e); - throw new CloudRuntimeException(basicErrMsg); - } finally { - if (snapshot.getSwiftId() != null) { - snapshotMgr.deleteSnapshotsDirForVolume( - secondaryStoragePoolUrl, dcId, accountId, volumeId); - } - } - } - - protected Answer cloneVolume(DataObject template, DataObject volume) { - VolumeInfo volInfo = (VolumeInfo)volume; - DiskOfferingVO offering = diskOfferingDao.findById(volInfo.getDiskOfferingId()); - VMTemplateStoragePoolVO tmpltStoredOn = templatePoolDao.findByPoolTemplate(template.getDataStore().getId(), template.getId()); - - DiskProfile diskProfile = new DiskProfile(volInfo, offering, - null); - CreateCommand cmd = new CreateCommand(diskProfile, - tmpltStoredOn.getLocalDownloadPath(), - new StorageFilerTO((StoragePool)template.getDataStore())); - Answer answer = null; - StoragePool pool = (StoragePool)volume.getDataStore(); - String errMsg = null; - try { - answer = storageMgr.sendToPool(pool, null, cmd); - } catch (StorageUnavailableException e) { - s_logger.debug("Failed to send to storage pool", e); - throw new CloudRuntimeException("Failed to send to storage pool", e); - } - - if (answer.getResult()) { - VolumeVO vol = this.volDao.findById(volume.getId()); - CreateAnswer createAnswer = (CreateAnswer) answer; - vol.setFolder(pool.getPath()); - vol.setPath(createAnswer.getVolume().getPath()); - vol.setSize(createAnswer.getVolume().getSize()); - vol.setPoolType(pool.getPoolType()); - vol.setPoolId(pool.getId()); - vol.setPodId(pool.getPodId()); - this.volDao.update(vol.getId(), vol); - - } else { - if (tmpltStoredOn != null - && (answer instanceof CreateAnswer) - && ((CreateAnswer) answer) - .templateReloadRequested()) { - if (!templateMgr - .resetTemplateDownloadStateOnPool(tmpltStoredOn - .getId())) { - - } - } - errMsg = answer.getDetails(); - } - - return answer; - } - - protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) { - VolumeInfo volume = (VolumeInfo)srcData; - VolumeInfo destVolume = (VolumeInfo)destData; - String secondaryStorageURL = this.templateMgr.getSecondaryStorageURL(volume - .getDataCenterId()); - StoragePool srcPool = (StoragePool)this.dataStoreMgr.getDataStore(volume - .getPoolId(), DataStoreRole.Primary); - - StoragePool destPool = (StoragePool)this.dataStoreMgr.getDataStore(destVolume.getPoolId(), DataStoreRole.Primary); - - String value = this.configDao.getValue(Config.CopyVolumeWait.toString()); - int _copyvolumewait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), - volume.getPath(), srcPool, secondaryStorageURL, true, - _copyvolumewait); - CopyVolumeAnswer cvAnswer; - try { - cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(srcPool, cvCmd); - } catch (StorageUnavailableException e1) { - throw new CloudRuntimeException( - "Failed to copy the volume from the source primary storage pool to secondary storage.", - e1); - } - - if (cvAnswer == null || !cvAnswer.getResult()) { - throw new CloudRuntimeException( - "Failed to copy the volume from the source primary storage pool to secondary storage."); - } - - String secondaryStorageVolumePath = cvAnswer.getVolumePath(); - - cvCmd = new CopyVolumeCommand(volume.getId(), - secondaryStorageVolumePath, destPool, - secondaryStorageURL, false, _copyvolumewait); - try { - cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool, cvCmd); - } catch (StorageUnavailableException e1) { - throw new CloudRuntimeException( - "Failed to copy the volume from secondary storage to the destination primary storage pool."); - } - - if (cvAnswer == null || !cvAnswer.getResult()) { - throw new CloudRuntimeException( - "Failed to copy the volume from secondary storage to the destination primary storage pool."); - } - - VolumeVO destVol = this.volDao.findById(destVolume.getId()); - destVol.setPath(cvAnswer.getVolumePath()); - this.volDao.update(destVol.getId(), destVol); - return cvAnswer; - } - - protected Answer migrateVolumeToPool(DataObject srcData, DataStore destStore) { - VolumeInfo volume = (VolumeInfo)srcData; - Long instanceId = volume.getInstanceId(); - StoragePool destPool = (StoragePool)this.dataStoreMgr.getDataStore(destStore.getId(), DataStoreRole.Primary); - MigrateVolumeAnswer answer = null; - VMInstanceVO vmInstance = null; - if (instanceId != null) { - vmInstance = instanceDao.findById(instanceId); - } - - Long hostId = null; - if (vmInstance != null) { - hostId = vmInstance.getHostId(); - } - - try { - if (hostId != null) { - MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool); - answer = (MigrateVolumeAnswer) this.agentMgr.send(hostId, command); - } - } catch (OperationTimedoutException e) { - s_logger.error("Operation timed out on storage motion for volume " + volume, e); - throw new CloudRuntimeException("Failed to live migrate volume " + volume + " to storage pool " + - destPool, e); - } catch (AgentUnavailableException e) { - s_logger.error("Agent unavailable exception while doing storage motion for volume " + volume, e); - throw new CloudRuntimeException("Failed to live migrate volume " + volume + " to storage pool " + - destPool, e); - } - - if (answer == null || !answer.getResult()) { - throw new CloudRuntimeException("Failed to migrate volume " + volume + " to storage pool " + destPool); - } else { - // Update the volume details after migration. - VolumeVO volumeVo = this.volDao.findById(volume.getId()); - Long oldPoolId = volume.getPoolId(); - volumeVo.setPath(answer.getVolumePath()); - volumeVo.setFolder(destPool.getPath()); - volumeVo.setPodId(destPool.getPodId()); - volumeVo.setPoolId(destPool.getId()); - volumeVo.setLastPoolId(oldPoolId); - this.volDao.update(volume.getId(), volumeVo); - } - - return answer; - } - - @Override - public Void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback) { - Answer answer = null; - String errMsg = null; - try { - if (destData.getType() == DataObjectType.VOLUME - && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Image) { - answer = copyVolumeFromImage(srcData, destData); - } else if (destData.getType() == DataObjectType.TEMPLATE - && srcData.getType() == DataObjectType.TEMPLATE) { - answer = copyTemplate(srcData, destData); - } else if (srcData.getType() == DataObjectType.SNAPSHOT - && destData.getType() == DataObjectType.VOLUME) { - answer = copyFromSnapshot(srcData, destData); - } else if (srcData.getType() == DataObjectType.SNAPSHOT - && destData.getType() == DataObjectType.TEMPLATE) { - answer = createTemplateFromSnashot(srcData, destData); - } else if (srcData.getType() == DataObjectType.VOLUME - && destData.getType() == DataObjectType.TEMPLATE) { - answer = createTemplateFromVolume(srcData, destData); - } else if (srcData.getType() == DataObjectType.TEMPLATE - && destData.getType() == DataObjectType.VOLUME) { - answer = cloneVolume(srcData, destData); - } else if (destData.getType() == DataObjectType.VOLUME - && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) { - if (srcData.getId() == destData.getId()) { - // The volume has to be migrated across storage pools. - answer = migrateVolumeToPool(srcData, destData.getDataStore()); - } else { - answer = copyVolumeBetweenPools(srcData, destData); - } - } else if (srcData.getType() == DataObjectType.SNAPSHOT && - destData.getType() == DataObjectType.SNAPSHOT) { - answer = copySnapshot(srcData, destData); - } - } catch (Exception e) { - s_logger.debug("copy failed", e); - errMsg = e.toString(); - } - CopyCommandResult result = new CopyCommandResult(null, answer); - result.setResult(errMsg); - callback.complete(result); - - return null; - } - - @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, - AsyncCompletionCallback callback) { - CopyCommandResult result = new CopyCommandResult(null, null); - result.setResult("Unsupported operation requested for copying data."); - callback.complete(result); - - return null; - } - - @DB - protected Answer createTemplateFromSnashot(DataObject srcData, - DataObject destData) { - long snapshotId = srcData.getId(); - SnapshotVO snapshot = snapshotDao.findById(snapshotId); - if (snapshot == null) { - throw new CloudRuntimeException("Unable to find Snapshot for Id " - + srcData.getId()); - } - Long zoneId = snapshot.getDataCenterId(); - HostVO secondaryStorageHost = this.templateMgr - .getSecondaryStorageHost(zoneId); - String secondaryStorageURL = snapshotMgr - .getSecondaryStorageURL(snapshot); - VMTemplateVO template = this.templateDao.findById(destData.getId()); - String name = template.getName(); - String backupSnapshotUUID = snapshot.getBackupSnapshotId(); - if (backupSnapshotUUID == null) { - throw new CloudRuntimeException( - "Unable to create private template from snapshot " - + snapshotId - + " due to there is no backupSnapshotUUID for this snapshot"); - } - - Long dcId = snapshot.getDataCenterId(); - Long accountId = snapshot.getAccountId(); - Long volumeId = snapshot.getVolumeId(); - - String origTemplateInstallPath = null; - List pools = this.storageMgr - .ListByDataCenterHypervisor(zoneId, - snapshot.getHypervisorType()); - if (pools == null || pools.size() == 0) { - throw new CloudRuntimeException( - "Unable to find storage pools in zone " + zoneId); - } - StoragePoolVO poolvo = pools.get(0); - StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore( - poolvo.getId(), DataStoreRole.Primary); - if (snapshot.getVersion() != null - && snapshot.getVersion().equalsIgnoreCase("2.1")) { - VolumeVO volume = this.volDao.findByIdIncludingRemoved(volumeId); - if (volume == null) { - throw new CloudRuntimeException("failed to upgrade snapshot " - + snapshotId + " due to unable to find orignal volume:" - + volumeId + ", try it later "); - } - if (volume.getTemplateId() == null) { - snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2"); - } else { - template = templateDao.findByIdIncludingRemoved(volume - .getTemplateId()); - if (template == null) { - throw new CloudRuntimeException( - "failed to upgrade snapshot " - + snapshotId - + " due to unalbe to find orignal template :" - + volume.getTemplateId() - + ", try it later "); - } - Long origTemplateId = template.getId(); - Long origTmpltAccountId = template.getAccountId(); - if (!this.volDao.lockInLockTable(volumeId.toString(), 10)) { - throw new CloudRuntimeException( - "failed to upgrade snapshot " + snapshotId - + " due to volume:" + volumeId - + " is being used, try it later "); - } - UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null, - secondaryStorageURL, dcId, accountId, volumeId, - origTemplateId, origTmpltAccountId, null, - snapshot.getBackupSnapshotId(), snapshot.getName(), - "2.1"); - if (!this.volDao.lockInLockTable(volumeId.toString(), 10)) { - throw new CloudRuntimeException( - "Creating template failed due to volume:" - + volumeId - + " is being used, try it later "); - } - Answer answer = null; - try { - answer = this.storageMgr.sendToPool(pool, cmd); - cmd = null; - } catch (StorageUnavailableException e) { - } finally { - this.volDao.unlockFromLockTable(volumeId.toString()); - } - if ((answer != null) && answer.getResult()) { - snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2"); - } else { - throw new CloudRuntimeException( - "Unable to upgrade snapshot"); - } - } - } - if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) { - snapshotMgr.downloadSnapshotsFromSwift(snapshot); - } - String value = configDao - .getValue(Config.CreatePrivateTemplateFromSnapshotWait - .toString()); - int _createprivatetemplatefromsnapshotwait = NumbersUtil.parseInt( - value, Integer - .parseInt(Config.CreatePrivateTemplateFromSnapshotWait - .getDefaultValue())); - - CreatePrivateTemplateFromSnapshotCommand cmd = new CreatePrivateTemplateFromSnapshotCommand( - pool, secondaryStorageURL, dcId, accountId, - snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(), - origTemplateInstallPath, template.getId(), name, - _createprivatetemplatefromsnapshotwait); - - return sendCommand(cmd, pool, template.getId(), dcId, - secondaryStorageHost.getId()); - } - - @DB - protected Answer sendCommand(Command cmd, StoragePool pool, - long templateId, long zoneId, long hostId) { - - CreatePrivateTemplateAnswer answer = null; - try { - answer = (CreatePrivateTemplateAnswer) this.storageMgr.sendToPool( - pool, cmd); - } catch (StorageUnavailableException e) { - throw new CloudRuntimeException( - "Failed to execute CreatePrivateTemplateFromSnapshotCommand", - e); - } - - if (answer == null || !answer.getResult()) { - return answer; - } - - VMTemplateVO privateTemplate = templateDao.findById(templateId); - String answerUniqueName = answer.getUniqueName(); - if (answerUniqueName != null) { - privateTemplate.setUniqueName(answerUniqueName); - } - ImageFormat format = answer.getImageFormat(); - if (format != null) { - privateTemplate.setFormat(format); - } else { - // This never occurs. - // Specify RAW format makes it unusable for snapshots. - privateTemplate.setFormat(ImageFormat.RAW); - } - - String checkSum = this.templateMgr - .getChecksum(hostId, answer.getPath()); - - - - privateTemplate.setChecksum(checkSum); - templateDao.update(privateTemplate.getId(), privateTemplate); - - // add template zone ref for this template - templateDao.addTemplateToZone(privateTemplate, zoneId); - VMTemplateHostVO templateHostVO = new VMTemplateHostVO(hostId, - privateTemplate.getId()); - templateHostVO.setDownloadPercent(100); - templateHostVO.setDownloadState(Status.DOWNLOADED); - templateHostVO.setInstallPath(answer.getPath()); - templateHostVO.setLastUpdated(new Date()); - templateHostVO.setSize(answer.getVirtualSize()); - templateHostVO.setPhysicalSize(answer.getphysicalSize()); - - templateHostDao.persist(templateHostVO); - - return answer; - } - - private Answer createTemplateFromVolume(DataObject srcObj, - DataObject destObj) { - long volumeId = srcObj.getId(); - VolumeVO volume = this.volDao.findById(volumeId); - if (volume == null) { - throw new CloudRuntimeException("Unable to find volume for Id " - + volumeId); - } - long accountId = volume.getAccountId(); - - String vmName = this.volumeMgr.getVmNameOnVolume(volume); - Long zoneId = volume.getDataCenterId(); - HostVO secondaryStorageHost = this.templateMgr - .getSecondaryStorageHost(zoneId); - if (secondaryStorageHost == null) { - throw new CloudRuntimeException( - "Can not find the secondary storage for zoneId " + zoneId); - } - String secondaryStorageURL = secondaryStorageHost.getStorageUrl(); - VMTemplateVO template = this.templateDao.findById(destObj.getId()); - StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore( - volume.getPoolId(), DataStoreRole.Primary); - String value = configDao - .getValue(Config.CreatePrivateTemplateFromVolumeWait.toString()); - int _createprivatetemplatefromvolumewait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CreatePrivateTemplateFromVolumeWait - .getDefaultValue())); - - CreatePrivateTemplateFromVolumeCommand cmd = new CreatePrivateTemplateFromVolumeCommand( - pool, secondaryStorageURL, destObj.getId(), accountId, - template.getName(), template.getUniqueName(), volume.getPath(), - vmName, _createprivatetemplatefromvolumewait); - - return sendCommand(cmd, pool, template.getId(), zoneId, - secondaryStorageHost.getId()); - } - - private HostVO getSecHost(long volumeId, long dcId) { - Long id = snapshotDao.getSecHostId(volumeId); - if ( id != null) { - return hostDao.findById(id); - } - return this.templateMgr.getSecondaryStorageHost(dcId); - } - - protected Answer copySnapshot(DataObject srcObject, DataObject destObject) { - SnapshotInfo srcSnapshot = (SnapshotInfo)srcObject; - VolumeInfo baseVolume = srcSnapshot.getBaseVolume(); - Long dcId = baseVolume.getDataCenterId(); - Long accountId = baseVolume.getAccountId(); - - HostVO secHost = getSecHost(baseVolume.getId(), baseVolume.getDataCenterId()); - Long secHostId = secHost.getId(); - String secondaryStoragePoolUrl = secHost.getStorageUrl(); - String snapshotUuid = srcSnapshot.getPath(); - // In order to verify that the snapshot is not empty, - // we check if the parent of the snapshot is not the same as the parent of the previous snapshot. - // We pass the uuid of the previous snapshot to the plugin to verify this. - SnapshotVO prevSnapshot = null; - String prevSnapshotUuid = null; - String prevBackupUuid = null; - - - SwiftTO swift = _swiftMgr.getSwiftTO(); - S3TO s3 = _s3Mgr.getS3TO(); - - long prevSnapshotId = srcSnapshot.getPrevSnapshotId(); - if (prevSnapshotId > 0) { - prevSnapshot = snapshotDao.findByIdIncludingRemoved(prevSnapshotId); - if ( prevSnapshot.getBackupSnapshotId() != null && swift == null) { - if (prevSnapshot.getVersion() != null && prevSnapshot.getVersion().equals("2.2")) { - prevBackupUuid = prevSnapshot.getBackupSnapshotId(); - prevSnapshotUuid = prevSnapshot.getPath(); - } - } else if ((prevSnapshot.getSwiftId() != null && swift != null) - || (prevSnapshot.getS3Id() != null && s3 != null)) { - prevBackupUuid = prevSnapshot.getBackupSnapshotId(); - prevSnapshotUuid = prevSnapshot.getPath(); - } - } - boolean isVolumeInactive = this.volumeMgr.volumeInactive(baseVolume); - String vmName = this.volumeMgr.getVmNameOnVolume(baseVolume); - StoragePool srcPool = (StoragePool)dataStoreMgr.getPrimaryDataStore(baseVolume.getPoolId()); - String value = configDao.getValue(Config.BackupSnapshotWait.toString()); - int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue())); - BackupSnapshotCommand backupSnapshotCommand = new BackupSnapshotCommand(secondaryStoragePoolUrl, dcId, accountId, baseVolume.getId(), srcSnapshot.getId(), secHostId, baseVolume.getPath(), srcPool, snapshotUuid, - srcSnapshot.getName(), prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, _backupsnapshotwait); - - if ( swift != null ) { - backupSnapshotCommand.setSwift(swift); - } else if (s3 != null) { - backupSnapshotCommand.setS3(s3); - } - BackupSnapshotAnswer answer = (BackupSnapshotAnswer) this.snapshotMgr.sendToPool(baseVolume, backupSnapshotCommand); - if (answer != null && answer.getResult()) { - SnapshotVO snapshotVO = this.snapshotDao.findById(srcSnapshot.getId()); - if (backupSnapshotCommand.getSwift() != null ) { - snapshotVO.setSwiftId(swift.getId()); - snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName()); - } else if (backupSnapshotCommand.getS3() != null) { - snapshotVO.setS3Id(s3.getId()); - snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName()); - } else { - snapshotVO.setSecHostId(secHost.getId()); - snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName()); - } - if (answer.isFull()) { - snapshotVO.setPrevSnapshotId(0L); - } - this.snapshotDao.update(srcSnapshot.getId(), snapshotVO); - } - return answer; - } - -} 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 0a91186aaab..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,166 +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 getPath() { - // TODO Auto-generated method stub - return null; - } + @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 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 State getState() { - // TODO Auto-generated method stub - return null; - } + @Override + public void updateDetail(String name, String value) { + // TODO Auto-generated method stub - @Override - public Type getRecurringType() { - // TODO Auto-generated method stub - return null; - } + } + + @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/to/ImageDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java deleted file mode 100644 index b1de88f0e2a..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java +++ /dev/null @@ -1,36 +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.image.datastore.ImageDataStoreInfo; - -public class ImageDataStoreTO { - private final String type; - private final String uri; - public ImageDataStoreTO(ImageDataStoreInfo dataStore) { - this.type = dataStore.getType(); - this.uri = dataStore.getUri(); - } - - public String getType() { - return this.type; - } - - public String getUri() { - return this.uri; - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimaryDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimaryDataStoreTO.java deleted file mode 100644 index a9a3cc43c0e..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimaryDataStoreTO.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 ImageOnPrimaryDataStoreTO { - private final String pathOnPrimaryDataStore; - private PrimaryDataStoreTO dataStore; - private final TemplateTO template; - public ImageOnPrimaryDataStoreTO(TemplateOnPrimaryDataStoreInfo template) { - this.pathOnPrimaryDataStore = template.getPath(); - //this.dataStore = template.getPrimaryDataStore().getDataStoreTO(); - this.template = new TemplateTO(template.getTemplate()); - } - - public String getPathOnPrimaryDataStore() { - return this.pathOnPrimaryDataStore; - } - - public PrimaryDataStoreTO getPrimaryDataStore() { - return this.dataStore; - } - - public TemplateTO getTemplate() { - return this.template; - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java deleted file mode 100644 index bc55ea8c3ea..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java +++ /dev/null @@ -1,51 +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.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreInfo; - -public class TemplateTO { - private final String path; - private final String uuid; - private DiskFormat diskType; - private final ImageDataStoreTO imageDataStore; - - public TemplateTO(TemplateInfo template) { - this.path = null; - this.uuid = template.getUuid(); - //this.diskType = template.getDiskType(); - this.imageDataStore = new ImageDataStoreTO((ImageDataStoreInfo)template.getDataStore()); - } - - public String getPath() { - return this.path; - } - - public String getUuid() { - return this.uuid; - } - - public DiskFormat getDiskType() { - return this.diskType; - } - - public ImageDataStoreTO getImageDataStore() { - return this.imageDataStore; - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java deleted file mode 100644 index c65b6525827..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java +++ /dev/null @@ -1,77 +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; -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 { - private final String uuid; - private final String path; - private VolumeType volumeType; - private DiskFormat diskType; - private PrimaryDataStoreTO dataStore; - private String name; - private final long size; - public VolumeTO(VolumeInfo volume) { - this.uuid = volume.getUuid(); - this.path = volume.getUri(); - //this.volumeType = volume.getType(); - //this.diskType = volume.getDiskType(); - if (volume.getDataStore() != null) { - this.dataStore = new PrimaryDataStoreTO((PrimaryDataStoreInfo)volume.getDataStore()); - } else { - this.dataStore = null; - } - //this.name = volume.getName(); - this.size = volume.getSize(); - } - - 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 PrimaryDataStoreTO getDataStore() { - return this.dataStore; - } - - public void setDataStore(PrimaryDataStoreTO dataStore) { - this.dataStore = dataStore; - } - - public String getName() { - return this.name; - } - - public long getSize() { - return this.size; - } -} 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 349f6ba9079..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 @@ -25,10 +25,8 @@ 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.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 +36,8 @@ import com.cloud.agent.api.StoragePoolInfo; 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.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolHostVO; @@ -48,8 +48,7 @@ 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 @@ -60,6 +59,7 @@ public class PrimaryDataStoreHelper { protected CapacityDao _capacityDao; @Inject protected StoragePoolHostDao storagePoolHostDao; + public DataStore createPrimaryDataStore(PrimaryDataStoreParameters params) { StoragePoolVO dataStoreVO = dataStoreDao.findPoolByUUID(params.getUuid()); if (dataStoreVO != null) { @@ -108,11 +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()); + this.storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, + pool.getUsedBytes()); return dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); } @@ -158,12 +159,9 @@ public class PrimaryDataStoreHelper { 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()); } @@ -176,26 +174,22 @@ public class PrimaryDataStoreHelper { } 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/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java similarity index 68% 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..9d174348c73 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; @@ -27,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()) { @@ -54,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, 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/datastore/DefaultPrimaryDataStore.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java similarity index 82% 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..cfdb5c0821d 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 @@ -25,17 +25,14 @@ 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.DataStoreRole; 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; 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; @@ -44,11 +41,16 @@ 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; +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; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.VMTemplateStoragePoolVO; @@ -60,9 +62,8 @@ import com.cloud.utils.component.ComponentContext; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.EncodingType; -public class DefaultPrimaryDataStore implements PrimaryDataStore { - private static final Logger s_logger = Logger - .getLogger(DefaultPrimaryDataStore.class); +public class PrimaryDataStoreImpl implements PrimaryDataStore { + private static final Logger s_logger = Logger.getLogger(PrimaryDataStoreImpl.class); protected PrimaryDataStoreDriver driver; protected StoragePoolVO pdsv; @Inject @@ -71,7 +72,7 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { @Inject private ObjectInDataStoreManager objectInStoreMgr; @Inject - ImageDataFactory imageDataFactory; + TemplateDataFactory imageDataFactory; @Inject SnapshotDataFactory snapshotFactory; protected DataStoreProvider provider; @@ -80,23 +81,22 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { @Inject StoragePoolHostDao poolHostDao; + @Inject private VolumeDao volumeDao; - public DefaultPrimaryDataStore() { - + public PrimaryDataStoreImpl() { + } - - public void configure(StoragePoolVO pdsv, - PrimaryDataStoreDriver driver, DataStoreProvider provider) { + + public void configure(StoragePoolVO pdsv, PrimaryDataStoreDriver driver, DataStoreProvider provider) { this.pdsv = pdsv; this.driver = driver; this.provider = provider; } - public static DefaultPrimaryDataStore createDataStore( - StoragePoolVO pdsv, PrimaryDataStoreDriver driver, + public static PrimaryDataStoreImpl createDataStore(StoragePoolVO pdsv, PrimaryDataStoreDriver driver, DataStoreProvider provider) { - DefaultPrimaryDataStore dataStore = (DefaultPrimaryDataStore)ComponentContext.inject(DefaultPrimaryDataStore.class); + PrimaryDataStoreImpl dataStore = ComponentContext.inject(PrimaryDataStoreImpl.class); dataStore.configure(pdsv, driver, provider); return dataStore; } @@ -153,14 +153,13 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { public Scope getScope() { StoragePoolVO vo = dataStoreDao.findById(this.pdsv.getId()); if (vo.getScope() == ScopeType.CLUSTER) { - return new ClusterScope(vo.getClusterId(), vo.getPodId(), - vo.getDataCenterId()); + return new ClusterScope(vo.getClusterId(), vo.getPodId(), vo.getDataCenterId()); } else if (vo.getScope() == ScopeType.ZONE) { return new ZoneScope(vo.getDataCenterId()); } 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()); } @@ -169,23 +168,19 @@ public class DefaultPrimaryDataStore 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; } - @Override public String getUuid() { return this.pdsv.getUuid(); @@ -218,25 +213,24 @@ public class DefaultPrimaryDataStore 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; } @Override public DataObject create(DataObject obj) { - //create template on primary storage + // create template on primary storage if (obj.getType() == DataObjectType.TEMPLATE) { - VMTemplateStoragePoolVO templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), obj.getId()); + VMTemplateStoragePoolVO templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), + obj.getId()); if (templateStoragePoolRef == null) { try { - templateStoragePoolRef = new VMTemplateStoragePoolVO(this.getId(), obj.getId()); - templateStoragePoolRef = templatePoolDao.persist(templateStoragePoolRef); + templateStoragePoolRef = new VMTemplateStoragePoolVO(this.getId(), obj.getId()); + templateStoragePoolRef = templatePoolDao.persist(templateStoragePoolRef); } catch (Throwable t) { templateStoragePoolRef = templatePoolDao.findByPoolTemplate(this.getId(), obj.getId()); if (templateStoragePoolRef == null) { @@ -244,16 +238,18 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { } } } - + } else if (obj.getType() == DataObjectType.SNAPSHOT) { + return objectInStoreMgr.create(obj, this); } - + return objectInStoreMgr.get(obj, this); } @Override public boolean delete(DataObject obj) { - // TODO Auto-generated method stub - return false; + //TODO: clean up through driver + objectInStoreMgr.delete(obj); + return true; } @Override @@ -268,27 +264,27 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { @Override public StoragePoolType getPoolType() { - return this.pdsv.getPoolType(); + return this.pdsv.getPoolType(); } @Override public Date getCreated() { - return this.pdsv.getCreated(); + return this.pdsv.getCreated(); } @Override public Date getUpdateTime() { - return this.pdsv.getUpdateTime(); + return this.pdsv.getUpdateTime(); } @Override public long getCapacityBytes() { - return this.pdsv.getCapacityBytes(); + return this.pdsv.getCapacityBytes(); } @Override - public long getAvailableBytes() { - return this.pdsv.getAvailableBytes(); + public long getUsedBytes() { + return this.pdsv.getUsedBytes(); } @Override @@ -308,7 +304,7 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { @Override public boolean isShared() { - return this.pdsv.getScope() == ScopeType.HOST ? false : true; + return this.pdsv.getScope() == ScopeType.HOST ? false : true; } @Override @@ -340,4 +336,14 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { public String getStorageProviderName() { return this.pdsv.getStorageProviderName(); } + + @Override + public DataStoreTO getTO() { + DataStoreTO to = getDriver().getStoreTO(this); + if (to == null) { + PrimaryDataStoreTO primaryTO = new PrimaryDataStoreTO(this); + return primaryTO; + } + return to; + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java deleted file mode 100644 index e5ee742f5ba..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java +++ /dev/null @@ -1,249 +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.driver; - -import java.net.URISyntaxException; -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.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 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.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; -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; - - -public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { - private static final Logger s_logger = Logger.getLogger(DefaultPrimaryDataStoreDriverImpl.class); - @Inject - EndPointSelector selector; - @Inject - StoragePoolHostDao storeHostDao; - @Inject - DataObjectManager dataObjMgr; - public DefaultPrimaryDataStoreDriverImpl() { - - } - - 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, CreateVolumeContext context) { - CreateCmdResult result = null; - CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult(); - if (volAnswer.getResult()) { - result = new CreateCmdResult(volAnswer.getPath(), volAnswer.getSize()); - } 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); - } - - public Void deleteCallback(AsyncCallbackDispatcher callback, AsyncRpcConext context) { - CommandResult result = new CommandResult(); - Answer answer = callback.getResult(); - if (!answer.getResult()) { - result.setResult(answer.getDetails()); - } - 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; - } - - } - - @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) { - 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) - .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()); - - 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(uri); - 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/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 86% 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..06b54e0a46c 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,10 +28,9 @@ 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; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.springframework.stereotype.Component; @@ -39,30 +38,30 @@ import org.springframework.stereotype.Component; import com.cloud.storage.StorageManager; @Component -public class DefaultPrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProviderManager { - @Inject - DataStoreProviderDao dataStoreProviderDao; +public class PrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProviderManager { @Inject DataStoreProviderManager providerManager; @Inject PrimaryDataStoreDao dataStoreDao; Map driverMaps; - @Inject StorageManager storageMgr; + @Inject + StorageManager storageMgr; @PostConstruct public void config() { driverMaps = new HashMap(); } - + @Override public PrimaryDataStore getPrimaryDataStore(long dataStoreId) { 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; } - + @Override public boolean registerDriver(String providerName, PrimaryDataStoreDriver driver) { if (driverMaps.get(providerName) != null) { 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 2f0b43ad9f6..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 @@ -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,22 +31,28 @@ 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; 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,22 +63,25 @@ 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.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/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 e09961913de..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.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; - -@Component -public class TemplateInstallStrategyImpl implements TemplateInstallStrategy { - private static final Logger s_logger = Logger - .getLogger(TemplateInstallStrategyImpl.class); - @Inject - ObjectInDataStoreManager objectInDataStoreMgr; - @Inject - DataMotionService motionSrv; - @Inject - ImageDataFactory 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 e0ecd165d7f..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 @@ -21,15 +21,15 @@ 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.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.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; @@ -38,24 +38,29 @@ 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.getUuid(), 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); @@ -66,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 deleted file mode 100644 index d3e8c543b54..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java +++ /dev/null @@ -1,204 +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/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 ea31be3d6a0..071c110da48 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 @@ -20,17 +20,27 @@ import java.util.Date; import javax.inject.Inject; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.dao.DiskOfferingDao; 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; 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.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.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; @@ -39,6 +49,8 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; import com.cloud.utils.storage.encoding.EncodingType; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.dao.VMInstanceDao; public class VolumeObject implements VolumeInfo { private static final Logger s_logger = Logger.getLogger(VolumeObject.class); @@ -48,13 +60,19 @@ public class VolumeObject implements VolumeInfo { @Inject VolumeDao volumeDao; @Inject - ObjectInDataStoreManager ojbectInStoreMgr; + VolumeDataStoreDao volumeStoreDao; + @Inject + ObjectInDataStoreManager objectInStoreMgr; + @Inject + VMInstanceDao vmInstanceDao; + @Inject + DiskOfferingDao diskOfferingDao; private Object payload; public VolumeObject() { _volStateMachine = Volume.State.getStateMachine(); } - + protected void configure(DataStore dataStore, VolumeVO volumeVO) { this.volumeVO = volumeVO; this.dataStore = dataStore; @@ -66,19 +84,34 @@ public class VolumeObject implements VolumeInfo { return vo; } + @Override + public String getAttachedVmName() { + Long vmId = this.volumeVO.getInstanceId(); + if (vmId != null) { + VMInstanceVO vm = vmInstanceDao.findById(vmId); + + if (vm == null) { + return null; + } + return vm.getInstanceName(); + } + return null; + } + @Override public String getUuid() { return volumeVO.getUuid(); } - public void setPath(String uuid) { - volumeVO.setPath(uuid); - } - - public void setSize(Long size) { - volumeVO.setSize(size); + public void setUuid(String uuid) { + volumeVO.setUuid(uuid); } + public void setSize(Long size) { + volumeVO.setSize(size); + } + + @Override public Volume.State getState() { return volumeVO.getState(); } @@ -96,9 +129,12 @@ public class VolumeObject implements VolumeInfo { public long getVolumeId() { return volumeVO.getId(); } + + @Override 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) { @@ -109,6 +145,50 @@ public class VolumeObject implements VolumeInfo { return result; } + private DiskOfferingVO getDiskOfferingVO() { + if (getDiskOfferingId() != null) { + DiskOfferingVO diskOfferingVO = diskOfferingDao.findById(getDiskOfferingId()); + return diskOfferingVO; + } + return null; + } + + @Override + public Long getBytesReadRate() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getBytesReadRate(); + } + return null; + } + + @Override + public Long getBytesWriteRate() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getBytesWriteRate(); + } + return null; + } + + @Override + public Long getIopsReadRate() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getIopsReadRate(); + } + return null; + } + + @Override + public Long getIopsWriteRate() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getIopsWriteRate(); + } + return null; + } + public void update() { volumeDao.update(volumeVO.getId(), volumeVO); volumeVO = volumeDao.findById(volumeVO.getId()); @@ -129,16 +209,15 @@ public class VolumeObject implements VolumeInfo { if (this.dataStore == null) { throw new CloudRuntimeException("datastore must be set before using this object"); } - DataObjectInStore obj = ojbectInStoreMgr.findObject(this.volumeVO.getUuid(), DataObjectType.VOLUME, this.dataStore.getUuid(), 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(); } } @@ -148,31 +227,31 @@ public class VolumeObject implements VolumeInfo { } @Override - public DiskFormat getFormat() { - // TODO Auto-generated method stub - return null; - } - - @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) { + objectInStoreMgr.update(this, event); + return; + } if (this.dataStore.getRole() == DataStoreRole.Image) { - ojbectInStoreMgr.update(this, event); - if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) { + 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 (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 || - 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; @@ -180,7 +259,7 @@ public class VolumeObject implements VolumeInfo { volEvent = Volume.Event.MigrationRequested; } } - + if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested) { volEvent = Volume.Event.DestroyRequested; } else if (event == ObjectInDataStoreStateMachine.Event.ExpungeRequested) { @@ -190,16 +269,37 @@ 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 { + // in case of OperationFailed, expunge the entry + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed + && (this.volumeVO.getState() != Volume.State.Copying && this.volumeVO.getState() != Volume.State.Uploaded)) { + objectInStoreMgr.delete(this); + } } } + @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(); @@ -217,7 +317,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.objectInStoreMgr.findObject(this, dataStore); + return objInStore.getInstallPath(); + } } @Override @@ -256,7 +361,7 @@ public class VolumeObject implements VolumeInfo { } @Override - public long getDiskOfferingId() { + public Long getDiskOfferingId() { return this.volumeVO.getDiskOfferingId(); } @@ -317,16 +422,180 @@ public class VolumeObject implements VolumeInfo { @Override public Object getpayload() { - return this.payload; + return this.payload; } - @Override - public HypervisorType getHypervisorType() { - return this.volumeDao.getHypervisorType(this.volumeVO.getId()); - } + public VolumeVO getVolume() { + return this.volumeVO; + } - @Override - public Long getLastPoolId() { - return this.volumeVO.getLastPoolId(); - } + @Override + public HypervisorType getHypervisorType() { + return this.volumeDao.getHypervisorType(this.volumeVO.getId()); + } + + @Override + public Long getLastPoolId() { + return this.volumeVO.getLastPoolId(); + } + + @Override + public DataTO getTO() { + DataTO to = this.getDataStore().getDriver().getTO(this); + if (to == null) { + to = new VolumeObjectTO(this); + } + return to; + } + + @Override + public void processEvent(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.processEvent(event); + + } + + public void incRefCount() { + if (this.dataStore == null) { + return; + } + + 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); + } + } + + @Override + public void decRefCount() { + if (this.dataStore == null) { + return; + } + 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); + } + } + + @Override + public Long getRefCount() { + if (this.dataStore == null) { + return null; + } + 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; + } + + @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(); + } + + @Override + public boolean delete() { + if (dataStore != null) { + return dataStore.delete(this); + } + return true; + } } 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 56a6651462b..95ca968ec00 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 @@ -19,6 +19,7 @@ package org.apache.cloudstack.storage.volume; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.Map; @@ -28,11 +29,13 @@ 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.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.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; @@ -43,24 +46,40 @@ 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.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.motion.DataMotionService; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.ListVolumeAnswer; +import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.to.VirtualMachineTO; +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.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; +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.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.VirtualMachine; -import com.cloud.vm.dao.VMInstanceDao; @Component public class VolumeServiceImpl implements VolumeService { @@ -76,11 +95,23 @@ public class VolumeServiceImpl implements VolumeService { @Inject DataMotionService motionSrv; @Inject - TemplateInstallStrategy templateInstallStrategy; - @Inject VolumeDataFactory volFactory; - @Inject SnapshotManager snapshotMgr; - @Inject VMInstanceDao vmDao; + @Inject + SnapshotManager snapshotMgr; + @Inject + ResourceLimitService _resourceLimitMgr; + @Inject + AccountManager _accountMgr; + @Inject + AlertManager _alertMgr; + @Inject + ConfigurationDao configDao; + @Inject + VolumeDataStoreDao _volumeStoreDao; + @Inject + VolumeDao _volumeDao; + @Inject + EndPointSelector _epSelector; public VolumeServiceImpl() { } @@ -114,26 +145,27 @@ 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; if (result.isSuccess()) { - vo.processEvent(Event.OperationSuccessed); + vo.processEvent(Event.OperationSuccessed, result.getAnswer()); } else { 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); } @@ -173,42 +205,42 @@ 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(); + // 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(); 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); @@ -231,28 +263,19 @@ 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); - } - } - class CreateBaseImageContext extends AsyncRpcConext { private final VolumeInfo volume; private final PrimaryDataStore dataStore; 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; @@ -279,27 +302,60 @@ 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); + 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); + } 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); + 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; + } + } try { motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller); @@ -308,13 +364,14 @@ 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; } @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()); @@ -327,59 +384,58 @@ 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; } 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; - public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, VolumeObject vo, - DataStore primaryStore, - DataObject templateOnStore, - AsyncCallFuture future) { + private final SnapshotInfo snapshot; + + public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, DataObject vo, + 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) { - 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)) - .setContext(context); - + protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, + PrimaryDataStore pd, AsyncCallFuture future) { 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; } @DB - public Void copyBaseImageCallBack(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { - VolumeObject vo = context.vo; + protected Void createVolumeFromBaseImageCallBack( + AsyncCallbackDispatcher callback, + CreateVolumeFromBaseImageContext context) { + DataObject vo = context.vo; CopyCommandResult result = callback.getResult(); - VolumeApiResult volResult = new VolumeApiResult(vo); + VolumeApiResult volResult = new VolumeApiResult((VolumeObject) 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()); @@ -392,11 +448,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); @@ -409,8 +465,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); @@ -422,19 +477,18 @@ 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); - volume = this.volFactory.getVolume(volume.getId(), store); - volume.processEvent(Event.CreateOnlyRequested); - CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, - (VolumeObject)volume, store, volumeOnStore, future); + 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); + 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); @@ -446,10 +500,12 @@ public class VolumeServiceImpl implements VolumeService { return future; } - protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher callback, + protected Void createVolumeFromSnapshotCallback( + AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { CopyCommandResult result = callback.getResult(); - VolumeInfo volume = context.vo; + VolumeInfo volume = (VolumeInfo) context.templateOnStore; + SnapshotInfo snapshot = context.snapshot; VolumeApiResult apiResult = new VolumeApiResult(volume); Event event = null; if (result.isFailed()) { @@ -460,7 +516,12 @@ public class VolumeServiceImpl implements VolumeService { } 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()); @@ -483,61 +544,176 @@ 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; } } - @Override - public AsyncCallFuture copyVolume(VolumeInfo srcVolume, - DataStore destStore) { + + protected AsyncCallFuture copyVolumeFromImageToPrimary(VolumeInfo srcVolume, DataStore destStore) { AsyncCallFuture future = new AsyncCallFuture(); VolumeApiResult res = new VolumeApiResult(srcVolume); + VolumeInfo destVolume = null; try { - if (!snapshotMgr.canOperateOnVolume(srcVolume)) { - s_logger.debug( - "There are snapshots creating on this volume, can not move this volume"); + destVolume = (VolumeInfo) destStore.create(srcVolume); + destVolume.processEvent(Event.CopyingRequested); + srcVolume.processEvent(Event.CopyingRequested); - res.setResult("There are snapshots creating on this volume, can not move this volume"); + 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; } + } - VolumeVO destVol = duplicateVolumeOnAnotherStorage(srcVolume, (StoragePool)destStore); - VolumeInfo destVolume = volFactory.getVolume(destVol.getId(), destStore); - destVolume.processEvent(Event.MigrationRequested); - srcVolume.processEvent(Event.MigrationRequested); + 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); + 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; + } + + + 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); + 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, destStore); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyVolumeCallBack(null, null)) + 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.getDataStore().delete(destVolume); + } + 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()) { + 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); // back to Ready state in Volume table + destVolume.processEventOnly(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) { + + if (srcVolume.getState() == Volume.State.Uploaded) { + return copyVolumeFromImageToPrimary(srcVolume, destStore); + } + + if (destStore.getRole() == DataStoreRole.Image) { + return copyVolumeFromPrimaryToImage(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"); + + 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); + VolumeInfo destVolume = volFactory.getVolume(destVol.getId(), destStore); + destVolume.processEvent(Event.MigrationRequested); + srcVolume.processEvent(Event.MigrationRequested); + + CopyVolumeContext context = new CopyVolumeContext(null, future, + srcVolume, destVolume, destStore); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + 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); + s_logger.debug("Failed to copy volume" + e); res.setResult(e.toString()); future.complete(res); } 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(); @@ -556,7 +732,7 @@ public class VolumeServiceImpl implements VolumeService { return null; } srcVolume.processEvent(Event.OperationSuccessed); - destVolume.processEvent(Event.OperationSuccessed); + destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); destroyVolume(srcVolume.getId()); srcVolume = volFactory.getVolume(srcVolume.getId()); AsyncCallFuture destroyFuture = expungeVolumeAsync(srcVolume); @@ -564,7 +740,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); } @@ -575,8 +751,8 @@ public class VolumeServiceImpl implements VolumeService { private class MigrateVolumeContext extends AsyncRpcConext { final VolumeInfo srcVolume; final VolumeInfo destVolume; - final DataStore destStore; final AsyncCallFuture future; + /** * @param callback */ @@ -585,7 +761,6 @@ public class VolumeServiceImpl implements VolumeService { super(callback); this.srcVolume = srcVolume; this.destVolume = destVolume; - this.destStore = destStore; this.future = future; } } @@ -620,7 +795,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); @@ -645,9 +819,7 @@ public class VolumeServiceImpl implements VolumeService { private class MigrateVmWithVolumesContext extends AsyncRpcConext { final Map volumeToPool; final AsyncCallFuture future; - /** - * @param callback - */ + public MigrateVmWithVolumesContext(AsyncCompletionCallback callback, AsyncCallFuture future, Map volumeToPool) { super(callback); @@ -662,7 +834,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()) { @@ -672,7 +845,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); } @@ -732,30 +906,42 @@ public class VolumeServiceImpl implements VolumeService { public AsyncCallFuture registerVolume(VolumeInfo volume, DataStore store) { AsyncCallFuture future = new AsyncCallFuture(); - VolumeObject vo = (VolumeObject) volume; + DataObject volumeOnStore = store.create(volume); - CreateVolumeContext context = new CreateVolumeContext(null, vo, future); + 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); + caller.setCallback(caller.getTarget().registerVolumeCallback(null, null)); + caller.setContext(context); - dataObjectMgr.createAsync(volume, store, caller, true); + store.getDriver().createAsync(volumeOnStore, caller); return future; } - protected Void registerVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { + protected Void registerVolumeCallback(AsyncCallbackDispatcher callback, + CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); - VolumeObject vo = (VolumeObject)context.volume; + try { + VolumeObject vo = (VolumeObject) context.volume; if (result.isFailed()) { - vo.stateTransit(Volume.Event.OperationFailed); + 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()); 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; + } } - @Override public AsyncCallFuture resize(VolumeInfo volume) { @@ -776,10 +962,11 @@ public class VolumeServiceImpl implements VolumeService { return future; } - protected Void resizeVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { + protected Void resizeVolumeCallback(AsyncCallbackDispatcher callback, + CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); AsyncCallFuture future = context.future; - VolumeInfo volume = (VolumeInfo)context.volume; + VolumeInfo volume = (VolumeInfo) context.volume; if (result.isFailed()) { try { @@ -795,7 +982,7 @@ public class VolumeServiceImpl implements VolumeService { try { volume.processEvent(Event.OperationSuccessed); - } catch(Exception e) { + } catch (Exception e) { s_logger.debug("Failed to change state", e); VolumeApiResult res = new VolumeApiResult(volume); res.setResult(result.getResult()); @@ -809,6 +996,158 @@ public class VolumeServiceImpl implements VolumeService { return null; } + @Override + public void handleVolumeSync(DataStore store) { + if (store == null) { + s_logger.warn("Huh? ssHost is null"); + return; + } + long storeId = store.getId(); + + 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 { + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), + com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() + - volInfo.getPhysicalSize()); + } catch (ResourceAllocationException e) { + s_logger.warn(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()); + } + } + } + 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 + VolumeInfo vol = volFactory.getVolume(volumeHost.getVolumeId()); + createVolumeAsync(vol, store); + } + } + + // Delete volumes which are not present on DB. + 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) { + ListVolumeCommand cmd = new ListVolumeCommand(store.getTO(), store.getUri()); + EndPoint ep = _epSelector.select(store); + Answer answer = ep.sendMessage(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; + } + + @Override + public SnapshotInfo takeSnapshot(VolumeInfo volume) { + 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); + } + } + + 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 122c3532a09..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("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"); - 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/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java index 8d91f5f79c1..dbfbd038dd1 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java @@ -22,16 +22,20 @@ package org.apache.cloudstack.framework.async; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Callback; +import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; +import org.apache.log4j.Logger; + @SuppressWarnings("rawtypes") public class AsyncCallbackDispatcher implements AsyncCompletionCallback { + private static final Logger s_logger = Logger.getLogger(AsyncCallbackDispatcher.class); + private Method _callbackMethod; - private T _targetObject; + private final T _targetObject; private Object _contextObject; private Object _resultObject; private AsyncCallbackDriver _driver = new InplaceAsyncCallbackDriver(); @@ -55,8 +59,13 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { @SuppressWarnings("unchecked") public T getTarget() { Enhancer en = new Enhancer(); - en.setSuperclass(_targetObject.getClass()); - en.setCallbacks(new Callback[] { new MethodInterceptor() { + 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, MethodProxy arg3) throws Throwable { @@ -74,14 +83,22 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { } }); en.setCallbackFilter(new CallbackFilter() { - public int accept(Method method) { + @Override + public int accept(Method method) { if (method.getParameterTypes().length == 0 && method.getName().equals("finalize")) { return 1; } return 0; }} ); + + try { return (T)en.create(); + } catch(Throwable e) { + s_logger.error("Unexpected exception", e); + } + + return null; } public AsyncCallbackDispatcher setCallback(Object useless) { @@ -98,7 +115,8 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { return (P)_contextObject; } - public void complete(Object resultObject) { + @Override + public void complete(Object resultObject) { _resultObject = resultObject; _driver.performCompletionCallback(this); } diff --git a/patches/systemvm/debian/buildsystemvm.sh b/patches/systemvm/debian/buildsystemvm.sh index 5134f89e7c1..c2fe34449f8 100755 --- a/patches/systemvm/debian/buildsystemvm.sh +++ b/patches/systemvm/debian/buildsystemvm.sh @@ -50,8 +50,8 @@ baseimage() { mount -o loop,offset=$offset $IMAGELOC $MOUNTPOINT - #debootstrap --variant=minbase --keyring=/usr/share/keyrings/debian-archive-keyring.gpg squeeze $MOUNTPOINT http://${APT_PROXY}${DEBIAN_MIRROR} - debootstrap --variant=minbase --arch=i386 squeeze $MOUNTPOINT http://${APT_PROXY}${DEBIAN_MIRROR} + #debootstrap --variant=minbase --keyring=/usr/share/keyrings/debian-archive-keyring.gpg wheezy $MOUNTPOINT http://${APT_PROXY}${DEBIAN_MIRROR} + debootstrap --variant=minbase --arch=i386 wheezy $MOUNTPOINT http://${APT_PROXY}${DEBIAN_MIRROR} } @@ -63,11 +63,14 @@ EOF fi cat > etc/apt/sources.list << EOF -deb http://ftp.us.debian.org/debian/ squeeze main contrib non-free -deb-src http://ftp.us.debian.org/debian/ squeeze main contrib non-free +deb http://ftp.us.debian.org/debian/ wheezy main contrib non-free +deb-src http://ftp.us.debian.org/debian/ wheezy main contrib non-free -deb http://security.debian.org/ squeeze/updates main -deb-src http://security.debian.org/ squeeze/updates main +deb http://security.debian.org/ wheezy/updates main +deb-src http://security.debian.org/ wheezy/updates main + +deb http://ftp.us.debian.org/debian/ wheezy-backports main +deb-src http://ftp.us.debian.org/debian/ wheezy-backports main EOF cat >> etc/apt/apt.conf << EOF @@ -347,7 +350,7 @@ packages() { export DEBIAN_FRONTEND DEBIAN_PRIORITY DEBCONF_DB_OVERRIDE #basic stuff - chroot . apt-get --no-install-recommends -q -y --force-yes install rsyslog logrotate cron chkconfig insserv net-tools ifupdown vim-tiny netbase iptables openssh-server grub-legacy e2fsprogs dhcp3-client dnsmasq tcpdump socat wget python bzip2 sed gawk diff grep gzip less tar telnet ftp rsync traceroute psmisc lsof procps monit inetutils-ping iputils-arping httping dnsutils zip unzip ethtool uuid file iproute acpid iptables-persistent virt-what sudo + chroot . apt-get --no-install-recommends -q -y --force-yes install rsyslog logrotate cron chkconfig insserv net-tools ifupdown vim-tiny netbase iptables openssh-server grub-legacy e2fsprogs dhcp3-client dnsmasq tcpdump socat wget python bzip2 sed gawk diffutils grep gzip less tar telnet ftp rsync traceroute psmisc lsof procps monit inetutils-ping iputils-arping httping dnsutils zip unzip ethtool uuid file iproute acpid iptables-persistent virt-what sudo #fix hostname in openssh-server generated keys sed -i "s/root@\(.*\)$/root@systemvm/g" etc/ssh/ssh_host_*.pub @@ -373,14 +376,8 @@ packages() { #ipcalc chroot . apt-get --no-install-recommends -q -y --force-yes install ipcalc - echo "***** getting sun jre 6*********" - chroot . echo 'sun-java6-bin shared/accepted-sun-dlj-v1-1 boolean true - sun-java6-jre shared/accepted-sun-dlj-v1-1 boolean true - sun-java6-jre sun-java6-jre/stopthread boolean true - sun-java6-jre sun-java6-jre/jcepolicy note - sun-java6-bin shared/present-sun-dlj-v1-1 note - sun-java6-jre shared/present-sun-dlj-v1-1 note ' | chroot . debconf-set-selections - chroot . apt-get --no-install-recommends -q -y install sun-java6-jre + echo "***** getting jre 7 *********" + chroot . apt-get --no-install-recommends -q -y install openjdk-7-jre-headless } @@ -409,7 +406,9 @@ services() { chroot . chkconfig xl2tpd off chroot . chkconfig --add cloud-early-config chroot . chkconfig cloud-early-config on - chroot . chkconfig --add cloud-passwd-srvr + chroot . chkconfig --add iptables-persistent + chroot . chkconfig iptables-persistent off + chroot . chkconfig --force --add cloud-passwd-srvr chroot . chkconfig cloud-passwd-srvr off chroot . chkconfig --add cloud chroot . chkconfig cloud off @@ -477,9 +476,9 @@ scriptdir=$(dirname $PWD/$0) rm -rf /tmp/systemvm mkdir -p /tmp/systemvm -cp ./xt_CHECKSUM.ko /tmp/systemvm -cp ./iptables_1.4.8-3local1checksum1_i386.deb /tmp/systemvm -cp ./xe-guest-utilities_5.6.0-595_i386.deb /tmp/systemvm +#cp ./xt_CHECKSUM.ko /tmp/systemvm +#cp ./iptables_1.4.8-3local1checksum1_i386.deb /tmp/systemvm +#cp ./xe-guest-utilities_5.6.0-595_i386.deb /tmp/systemvm rm -f $IMAGELOC begin=$(date +%s) diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 0dcd5710664..f93c39d81e8 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -112,6 +112,9 @@ get_boot_params() { sed -i "s/%/ /g" /var/cache/cloud/cmdline ;; kvm) + if [ ! -e /dev/vport0p1 ]; then + log_it "/dev/vport0p1 not loaded, perhaps guest kernel is too old." && exit 2 + fi while read line; do if [[ $line == cmdline:* ]]; then cmd=${line//cmdline:/} @@ -133,7 +136,7 @@ get_boot_params() { mount -t ntfs /dev/sdb1 $EXTRA_MOUNT cp -f $EXTRA_MOUNT/cmdline /var/cache/cloud/cmdline umount $EXTRA_MOUNT - ;; + ;; esac } @@ -540,6 +543,8 @@ setup_dnsmasq() { NS6=${NS6%?} [ $ETH0_IP ] && echo "dhcp-option=6,$NS" >> /etc/dnsmasq.conf [ $ETH0_IP6 ] && echo "dhcp-option=option6:dns-server,$NS6" >> /etc/dnsmasq.conf +#adding the name data-server to the /etc/hosts for allowing the access to user-data service and ssh-key reset in every subnet. + echo "$ETH0_IP data-server" >> /etc/hosts } setup_sshd(){ diff --git a/patches/systemvm/debian/config/root/createIpAlias.sh b/patches/systemvm/debian/config/root/createIpAlias.sh index 2c798131fd4..1db210b6860 100755 --- a/patches/systemvm/debian/config/root/createIpAlias.sh +++ b/patches/systemvm/debian/config/root/createIpAlias.sh @@ -32,4 +32,7 @@ do netmask=$(echo $var1 | cut -f3 -d ":") ifconfig eth0:$alias_count $routerip netmask $netmask up var=$( echo $var | sed "s/${var1}-//" ) -done \ No newline at end of file +done +#restaring the password service to enable it on the ip aliases +/etc/init.d/cloud-passwd-srvr restart +exit $? \ No newline at end of file diff --git a/patches/systemvm/debian/config/root/edithosts.sh b/patches/systemvm/debian/config/root/edithosts.sh index fb0c34fbd42..eaa82927803 100755 --- a/patches/systemvm/debian/config/root/edithosts.sh +++ b/patches/systemvm/debian/config/root/edithosts.sh @@ -69,7 +69,9 @@ HOSTS=/etc/hosts source /root/func.sh lock="biglock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as DhcpEntryCommand is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/patches/systemvm/debian/config/root/firewallRule_egress.sh b/patches/systemvm/debian/config/root/firewallRule_egress.sh index 0da7718741d..b1e7a403520 100755 --- a/patches/systemvm/debian/config/root/firewallRule_egress.sh +++ b/patches/systemvm/debian/config/root/firewallRule_egress.sh @@ -82,15 +82,14 @@ fw_entry_for_egress() { [ "$eport" == "-1" ] && typecode="$sport" [ "$sport" == "-1" ] && typecode="any" sudo iptables -A FW_EGRESS_RULES -p $prot -s $lcidr --icmp-type $typecode \ - -j ACCEPT + -j $target result=$? elif [ "$prot" == "all" ] then - sudo iptables -A FW_EGRESS_RULES -p $prot -s $lcidr -j ACCEPT + sudo iptables -A FW_EGRESS_RULES -p $prot -s $lcidr -j $target result=$? else - sudo iptables -A FW_EGRESS_RULES -p $prot -s $lcidr \ - $DPORT -j ACCEPT + sudo iptables -A FW_EGRESS_RULES -p $prot -s $lcidr $DPORT -j $target result=$? fi @@ -109,14 +108,18 @@ rules="" rules_list="" ip="" dev="" +pflag=0 shift shift -while getopts 'a:' OPTION +while getopts 'a:P:' OPTION do case $OPTION in a) aflag=1 rules="$OPTARG" ;; + P) pflag=1 + pvalue="$OPTARG" + ;; ?) usage unlock_exit 2 $lock $locked ;; @@ -142,6 +145,13 @@ fi success=0 +if [ "$pvalue" == "0" -o "$pvalue" == "2" ] + then + target="ACCEPT" + else + target="DROP" + fi + fw_egress_chain for r in $rules_list do @@ -162,6 +172,12 @@ then fw_egress_backup_restore else logger -t cloud "deleting backup for guest network" + if [ "$pvalue" == "1" -o "$pvalue" == "2" ] + then + #Adding default policy rule + sudo iptables -A FW_EGRESS_RULES -j ACCEPT + fi + fi fw_egress_remove_backup diff --git a/patches/systemvm/debian/config/root/savepassword.sh b/patches/systemvm/debian/config/root/savepassword.sh index a096b862fce..fc736039c2e 100755 --- a/patches/systemvm/debian/config/root/savepassword.sh +++ b/patches/systemvm/debian/config/root/savepassword.sh @@ -25,7 +25,9 @@ source /root/func.sh lock="passwdlock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as password reset command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/patches/systemvm/debian/config/root/userdata.sh b/patches/systemvm/debian/config/root/userdata.sh index e5d170b5b23..f9ea644c2fd 100644 --- a/patches/systemvm/debian/config/root/userdata.sh +++ b/patches/systemvm/debian/config/root/userdata.sh @@ -21,7 +21,9 @@ source /root/func.sh lock="biglock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as userdata command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java index edb5dea8ca5..997d754a326 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java @@ -92,10 +92,11 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R public Map> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) throws DiscoveryException { + /* Enable this after we decide to use addBaremetalHostCmd instead of addHostCmd String discoverName = _params.get(ApiConstants.BAREMETAL_DISCOVER_NAME); if (!this.getClass().getName().equals(discoverName)) { return null; - } + } */ Map> resources = new HashMap>(); Map details = new HashMap(); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java index 928183ba3df..ae2165a5565 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java @@ -5,20 +5,20 @@ // 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. -// +// // Automatically generated by addcopyright.py at 01/29/2013 // Apache License, Version 2.0 (the "License"); you may not use this // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// +// // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.baremetal.manager; @@ -31,6 +31,7 @@ import javax.inject.Inject; 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.RegisterTemplateCmd; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import com.cloud.configuration.Resource.ResourceType; @@ -64,11 +65,11 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem public String getName() { return TemplateAdapterType.BareMetal.getName(); } - + @Override public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException { TemplateProfile profile = super.prepare(cmd); - + if (profile.getZoneId() == null || profile.getZoneId() == -1) { List dcs = _dcDao.listAllIncludingRemoved(); for (DataCenterVO dc : dcs) { @@ -84,127 +85,112 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem } } - // Check that the resource limit for secondary storage won't be exceeded - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()), - ResourceType.secondary_storage, UriUtils.getRemoteSize(profile.getUrl())); - 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())); return template; } 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 +211,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/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java index b41d6ca0426..f4c290c4592 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java @@ -26,6 +26,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.AddBaremetalHostCmd; import org.apache.log4j.Logger; import com.cloud.agent.api.StopAnswer; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java index 4845bd1fe85..12bad0292c4 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java @@ -31,6 +31,8 @@ import java.util.Map; import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.api.AddBaremetalPxeCmd; +import org.apache.cloudstack.api.AddBaremetalPxePingServerCmd; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java index 20554e6b683..48c5ba2f635 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java @@ -184,60 +184,70 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource if (scriptPath == null) { throw new ConfigurationException("Cannot find ping script " + scriptPath); } - _pingCommand = new Script2(scriptPath, s_logger); + String pythonPath = "/usr/bin/python"; + _pingCommand = new Script2(pythonPath, s_logger); + _pingCommand.add(scriptPath); _pingCommand.add("ping"); _pingCommand.add("hostname=" + _ip); _pingCommand.add("usrname=" + _username); _pingCommand.add("password=" + _password, ParamType.PASSWORD); - _setPxeBootCommand = new Script2(scriptPath, s_logger); + _setPxeBootCommand = new Script2(pythonPath, s_logger); + _setPxeBootCommand.add(scriptPath); _setPxeBootCommand.add("boot_dev"); _setPxeBootCommand.add("hostname=" + _ip); _setPxeBootCommand.add("usrname=" + _username); _setPxeBootCommand.add("password=" + _password, ParamType.PASSWORD); _setPxeBootCommand.add("dev=pxe"); - _setDiskBootCommand = new Script2(scriptPath, s_logger); + _setDiskBootCommand = new Script2(pythonPath, s_logger); + _setDiskBootCommand.add(scriptPath); _setDiskBootCommand.add("boot_dev"); _setDiskBootCommand.add("hostname=" + _ip); _setDiskBootCommand.add("usrname=" + _username); _setDiskBootCommand.add("password=" + _password, ParamType.PASSWORD); _setDiskBootCommand.add("dev=disk"); - _rebootCommand = new Script2(scriptPath, s_logger); + _rebootCommand = new Script2(pythonPath, s_logger); + _rebootCommand.add(scriptPath); _rebootCommand.add("reboot"); _rebootCommand.add("hostname=" + _ip); _rebootCommand.add("usrname=" + _username); _rebootCommand.add("password=" + _password, ParamType.PASSWORD); - _getStatusCommand = new Script2(scriptPath, s_logger); + _getStatusCommand = new Script2(pythonPath, s_logger); + _getStatusCommand.add(scriptPath); _getStatusCommand.add("ping"); _getStatusCommand.add("hostname=" + _ip); _getStatusCommand.add("usrname=" + _username); _getStatusCommand.add("password=" + _password, ParamType.PASSWORD); - _powerOnCommand = new Script2(scriptPath, s_logger); + _powerOnCommand = new Script2(pythonPath, s_logger); + _powerOnCommand.add(scriptPath); _powerOnCommand.add("power"); _powerOnCommand.add("hostname=" + _ip); _powerOnCommand.add("usrname=" + _username); _powerOnCommand.add("password=" + _password, ParamType.PASSWORD); _powerOnCommand.add("action=on"); - _powerOffCommand = new Script2(scriptPath, s_logger); + _powerOffCommand = new Script2(pythonPath, s_logger); + _powerOffCommand.add(scriptPath); _powerOffCommand.add("power"); _powerOffCommand.add("hostname=" + _ip); _powerOffCommand.add("usrname=" + _username); _powerOffCommand.add("password=" + _password, ParamType.PASSWORD); _powerOffCommand.add("action=soft"); - _forcePowerOffCommand = new Script2(scriptPath, s_logger); + _forcePowerOffCommand = new Script2(pythonPath, s_logger); + _forcePowerOffCommand.add(scriptPath); _forcePowerOffCommand.add("power"); _forcePowerOffCommand.add("hostname=" + _ip); _forcePowerOffCommand.add("usrname=" + _username); _forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD); _forcePowerOffCommand.add("action=off"); - _bootOrRebootCommand = new Script2(scriptPath, s_logger); + _bootOrRebootCommand = new Script2(pythonPath, s_logger); + _bootOrRebootCommand.add(scriptPath); _bootOrRebootCommand.add("boot_or_reboot"); _bootOrRebootCommand.add("hostname=" + _ip); _bootOrRebootCommand.add("usrname=" + _username); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java index e9d5499e49a..6d266fd4814 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java @@ -175,12 +175,14 @@ public class BaremetalDhcpElement extends AdapterBase implements DhcpServiceProv @Override public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - return false; //To change body of implemented methods use File | Settings | File Templates. + //TODO Add support for baremetal + return true; } @Override public boolean removeDhcpSupportForSubnet(Network network) { - return false; //To change body of implemented methods use File | Settings | File Templates. + //TODO Add support for baremetal + return true; } } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java index fa4c7afd97f..564caa20dbb 100644 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java @@ -24,6 +24,8 @@ package com.cloud.baremetal.networkservice; import java.util.List; +import org.apache.cloudstack.api.AddBaremetalDhcpCmd; + import com.cloud.baremetal.database.BaremetalDhcpVO; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ResourceUnavailableException; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java index 54e4fff4e90..1406b44a285 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java @@ -32,6 +32,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.AddBaremetalDhcpCmd; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -53,6 +54,7 @@ import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.network.Network; +import com.cloud.network.NetworkModel; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; @@ -100,6 +102,8 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; @Inject BaremetalDhcpDao _extDhcpDao; + @Inject + NetworkModel _ntwkModel; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -147,7 +151,7 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh dns = nic.getDns2(); } DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), profile.getVirtualMachine().getHostName(), null, dns, - nic.getGateway(), null); + nic.getGateway(), null, _ntwkModel.getExecuteInSeqNtwkElmtCmd()); String errMsg = String.format("Set dhcp entry on external DHCP %1$s failed(ip=%2$s, mac=%3$s, vmname=%4$s)", h.getPrivateIpAddress(), nic.getIp4Address(), nic.getMacAddress(), profile.getVirtualMachine().getHostName()); // prepareBareMetalDhcpEntry(nic, dhcpCommand); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java index 09f8f6a0abc..4f638e8291c 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java @@ -27,6 +27,8 @@ import java.util.Map; import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.api.AddBaremetalKickStartPxeCmd; +import org.apache.cloudstack.api.AddBaremetalPxeCmd; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java index b31932db7ea..f02591e4ca8 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java @@ -24,6 +24,8 @@ package com.cloud.baremetal.networkservice; import java.util.List; +import org.apache.cloudstack.api.AddBaremetalPxeCmd; + import com.cloud.baremetal.database.BaremetalPxeVO; import com.cloud.deploy.DeployDestination; import com.cloud.host.HostVO; @@ -60,5 +62,5 @@ public interface BaremetalPxeManager extends Manager, PluggableService { public static final String BAREMETAL_PXE_CAPABILITY = "BaremetalPxe"; public static final String BAREMETAL_PXE_SERVICE_PROPERTIES = "baremetalpxe_commands.properties"; public static final Provider BAREMETAL_PXE_SERVICE_PROVIDER = new Provider("BaremetalPxeProvider", true);; - public static final Provider BAREMETAL_USERDATA_PROVIDER = new Provider("BaremetaUserdataProvider", true); + public static final Provider BAREMETAL_USERDATA_PROVIDER = new Provider("BaremetalUserdataProvider", true); } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java index e88d302af37..17af47f6003 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java @@ -31,6 +31,9 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.AddBaremetalKickStartPxeCmd; +import org.apache.cloudstack.api.AddBaremetalPxeCmd; +import org.apache.cloudstack.api.AddBaremetalPxePingServerCmd; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -45,6 +48,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.network.NetworkModel; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.resource.ResourceManager; @@ -81,6 +85,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe @Inject NicDao _nicDao; @Inject ConfigurationDao _configDao; @Inject PhysicalNetworkDao _phynwDao; + @Inject NetworkModel _ntwkModel; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -184,7 +189,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText(); String zoneName = _dcDao.findById(vm.getDataCenterId()).getName(); NicVO nvo = _nicDao.findById(nic.getId()); - VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName()); + VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName(), _ntwkModel.getExecuteInSeqNtwkElmtCmd()); cmd.addVmData("userdata", "user-data", vm.getUserData()); cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering)); cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName)); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java index 6a03e88dd23..feb23be23d0 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java @@ -24,6 +24,8 @@ package com.cloud.baremetal.networkservice; import java.util.List; +import org.apache.cloudstack.api.AddBaremetalPxeCmd; + import com.cloud.baremetal.database.BaremetalPxeVO; import com.cloud.deploy.DeployDestination; import com.cloud.uservm.UserVm; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalDhcpCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java similarity index 97% rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalDhcpCmd.java rename to plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java index dc69dce92bf..04c913726fa 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalDhcpCmd.java +++ b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java @@ -16,7 +16,7 @@ // under the License. // // Automatically generated by addcopyright.py at 01/29/2013 -package com.cloud.baremetal.networkservice; +package org.apache.cloudstack.api; import javax.inject.Inject; @@ -35,6 +35,8 @@ import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import com.cloud.baremetal.database.BaremetalDhcpVO; +import com.cloud.baremetal.networkservice.BaremetalDhcpManager; +import com.cloud.baremetal.networkservice.BaremetalDhcpResponse; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/AddBaremetalHostCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalHostCmd.java similarity index 95% rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/AddBaremetalHostCmd.java rename to plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalHostCmd.java index 8d459028a17..6bc18191ed2 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/AddBaremetalHostCmd.java +++ b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalHostCmd.java @@ -16,13 +16,15 @@ // under the License. // // Automatically generated by addcopyright.py at 01/29/2013 -package com.cloud.baremetal.manager; +package org.apache.cloudstack.api; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.command.admin.host.AddHostCmd; import org.apache.cloudstack.api.response.HostResponse; + +import com.cloud.baremetal.manager.BareMetalDiscoverer; @APICommand(name="addBaremetalHost", description="add a baremetal host", responseObject = HostResponse.class) public class AddBaremetalHostCmd extends AddHostCmd { diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalKickStartPxeCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalKickStartPxeCmd.java similarity index 93% rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalKickStartPxeCmd.java rename to plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalKickStartPxeCmd.java index 8bcc7c13f62..3adab207737 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalKickStartPxeCmd.java +++ b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalKickStartPxeCmd.java @@ -16,12 +16,14 @@ // under the License. // // Automatically generated by addcopyright.py at 01/29/2013 -package com.cloud.baremetal.networkservice; +package org.apache.cloudstack.api; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd.CommandType; import org.apache.cloudstack.api.Parameter; + +import com.cloud.baremetal.networkservice.BaremetalPxeKickStartResponse; @APICommand(name="addBaremetalPxeKickStartServer", description="add a baremetal pxe server", responseObject = BaremetalPxeKickStartResponse.class) public class AddBaremetalKickStartPxeCmd extends AddBaremetalPxeCmd { @Parameter(name=ApiConstants.TFTP_DIR, type=CommandType.STRING, required = true, description="Tftp root directory of PXE server") diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxeCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxeCmd.java similarity index 98% rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxeCmd.java rename to plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxeCmd.java index eeb73862cc2..49effca5bc6 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxeCmd.java +++ b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxeCmd.java @@ -16,7 +16,7 @@ // under the License. // // Automatically generated by addcopyright.py at 01/29/2013 -package com.cloud.baremetal.networkservice; +package org.apache.cloudstack.api; import javax.inject.Inject; @@ -35,6 +35,7 @@ import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import com.cloud.baremetal.database.BaremetalPxeVO; +import com.cloud.baremetal.networkservice.BaremetalPxeManager; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxePingServerCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxePingServerCmd.java similarity index 96% rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxePingServerCmd.java rename to plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxePingServerCmd.java index 01cafd435da..2ec9ecf1ae8 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxePingServerCmd.java +++ b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxePingServerCmd.java @@ -16,12 +16,14 @@ // under the License. // // Automatically generated by addcopyright.py at 01/29/2013 -package com.cloud.baremetal.networkservice; +package org.apache.cloudstack.api; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.Parameter; +import com.cloud.baremetal.networkservice.BaremetalPxePingResponse; + @APICommand(name="addBaremetalPxePingServer", description="add a baremetal ping pxe server", responseObject = BaremetalPxePingResponse.class) public class AddBaremetalPxePingServerCmd extends AddBaremetalPxeCmd { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java index b897df2ecf3..0db83cc5750 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java @@ -91,36 +91,38 @@ public class BridgeVifDriver extends VifDriverBase { } String trafficLabel = nic.getName(); if (nic.getType() == Networks.TrafficType.Guest) { + Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0; if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { if(trafficLabel != null && !trafficLabel.isEmpty()) { s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel); String brName = createVlanBr(vlanId, _pifs.get(trafficLabel)); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } else { String brName = createVlanBr(vlanId, _pifs.get("private")); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else { - intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else if (nic.getType() == Networks.TrafficType.Control) { /* Make sure the network is still there */ createControlNetwork(); intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType)); } else if (nic.getType() == Networks.TrafficType.Public) { + Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0; if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { if(trafficLabel != null && !trafficLabel.isEmpty()){ s_logger.debug("creating a vlan dev and bridge for public traffic per traffic label " + trafficLabel); String brName = createVlanBr(vlanId, _pifs.get(trafficLabel)); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } else { String brName = createVlanBr(vlanId, _pifs.get("public")); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else { - intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType)); + intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType), networkRateKBps); } } else if (nic.getType() == Networks.TrafficType.Management) { intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType)); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java index 1946d74a495..425abbac145 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java @@ -47,12 +47,14 @@ public class DirectVifDriver extends VifDriverBase { LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef(); if (nic.getType() == Networks.TrafficType.Guest) { + Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0; intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType), - _libvirtComputingResource.getNetworkDirectSourceMode()); + _libvirtComputingResource.getNetworkDirectSourceMode(), networkRateKBps); } else if (nic.getType() == Networks.TrafficType.Public) { + Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1)? nic.getNetworkRateMbps().intValue() * 128: 0; intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType), - _libvirtComputingResource.getNetworkDirectSourceMode()); + _libvirtComputingResource.getNetworkDirectSourceMode(), networkRateKBps); } return intf; @@ -62,4 +64,4 @@ public class DirectVifDriver extends VifDriverBase { // not needed, libvirt will cleanup } -} \ No newline at end of file +} 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 1d847d12c9e..a5548c51b6d 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 @@ -66,6 +66,9 @@ import org.libvirt.DomainSnapshot; import org.libvirt.LibvirtException; import org.libvirt.NodeInfo; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +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; @@ -91,9 +94,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; @@ -174,7 +174,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.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; @@ -205,6 +209,7 @@ 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; @@ -218,11 +223,13 @@ 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.TemplateInfo; 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; @@ -338,6 +345,8 @@ ServerResource { protected HypervisorType _hypervisorType; protected String _hypervisorURI; + protected long _hypervisorLibvirtVersion; + protected long _hypervisorQemuVersion; protected String _hypervisorPath; protected String _networkDirectSourceMode; protected String _networkDirectDevice; @@ -354,7 +363,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; @@ -393,6 +401,8 @@ ServerResource { protected BridgeType _bridgeType; + protected StorageSubsystemCommandHandler storageHandler; + private String getEndIpFromStartIp(String startIp, int numIps) { String[] tokens = startIp.split("[.]"); assert (tokens.length == 4); @@ -460,7 +470,7 @@ ServerResource { } protected String getDefaultDomrScriptsDir() { - return "scripts/network/domr/kvm"; + return "scripts/network/domr"; } protected String getNetworkDirectSourceMode() { @@ -693,7 +703,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"); @@ -737,6 +747,8 @@ ServerResource { try { _hvVersion = conn.getVersion(); _hvVersion = (_hvVersion % 1000000) / 1000; + _hypervisorLibvirtVersion = conn.getLibVirVersion(); + _hypervisorQemuVersion = conn.getVersion(); } catch (LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } @@ -832,6 +844,10 @@ ServerResource { configureVifDrivers(params); + KVMStorageProcessor storageProcessor = new KVMStorageProcessor(_storagePoolMgr, this); + storageProcessor.configure(name, params); + storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); + return true; } @@ -980,11 +996,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"); @@ -1243,6 +1254,8 @@ ServerResource { return execute((CheckNetworkCommand) cmd); } else if (cmd instanceof NetworkRulesVmSecondaryIpCommand) { return execute((NetworkRulesVmSecondaryIpCommand) cmd); + } else if (cmd instanceof StorageSubSystemCommand) { + return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else if (cmd instanceof PvlanSetupCommand) { return execute((PvlanSetupCommand) cmd); } else { @@ -1413,6 +1426,10 @@ ServerResource { VolumeTO volume = new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), pool.getPath(), vol.getName(), vol.getName(), disksize, null); + volume.setBytesReadRate(dskch.getBytesReadRate()); + volume.setBytesWriteRate(dskch.getBytesWriteRate()); + volume.setIopsReadRate(dskch.getIopsReadRate()); + volume.setIopsWriteRate(dskch.getIopsWriteRate()); return new CreateAnswer(cmd, volume); } catch (CloudRuntimeException e) { s_logger.debug("Failed to create volume: " + e.toString()); @@ -1545,8 +1562,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()); @@ -1714,7 +1729,6 @@ ServerResource { try { conn = LibvirtConnection.getConnectionByVmName(routerName); - Domain vm = getDomain(conn, routerName); List pluggedNics = getInterfaces(conn, routerName); InterfaceDef routerNic = null; @@ -1729,7 +1743,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, @@ -1748,15 +1761,11 @@ 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); String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); try { - conn = LibvirtConnection.getConnectionByVmName(routerName); - Domain vm = getDomain(conn, routerName); String [][] rules = cmd.generateFwRules(); String[] aclRules = rules[0]; NicTO nic = cmd.getNic(); @@ -1780,7 +1789,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); @@ -1795,7 +1804,6 @@ ServerResource { try { conn = LibvirtConnection.getConnectionByVmName(routerName); - Domain vm = getDomain(conn, routerName); Integer devNum = 0; String pubVlan = pubIP.getVlanId(); List pluggedNics = getInterfaces(conn, routerName); @@ -1842,7 +1850,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); @@ -2028,7 +2035,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(); @@ -2124,66 +2130,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 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) { @@ -2303,7 +2249,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; @@ -2399,10 +2344,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) { @@ -2481,7 +2422,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(), @@ -2490,7 +2430,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); @@ -2628,7 +2568,7 @@ ServerResource { cmd.getPoolUuid()); KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk, - cmd.getDeviceId().intValue()); + cmd.getDeviceId().intValue(), cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate()); } catch (LibvirtException e) { return new AttachVolumeAnswer(cmd, e.toString()); } catch (InternalErrorException e) { @@ -2813,8 +2753,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); } @@ -3229,6 +3169,8 @@ ServerResource { } else { guest.setGuestType(GuestDef.guestType.KVM); vm.setHvsType(HypervisorType.KVM.toString().toLowerCase()); + vm.setLibvirtVersion(_hypervisorLibvirtVersion); + vm.setQemuVersion(_hypervisorQemuVersion); } guest.setGuestArch(vmTO.getArch()); guest.setMachineType("pc"); @@ -3415,10 +3357,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); @@ -3427,26 +3373,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); @@ -3454,10 +3402,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; @@ -3475,7 +3424,7 @@ ServerResource { disk.defISODisk(volPath); } } else { - int devId = (int) volume.getDeviceId(); + int devId = volume.getDiskSeq().intValue(); if (pool.getType() == StoragePoolType.RBD) { /* @@ -3502,6 +3451,17 @@ ServerResource { } + VolumeObjectTO volumeObjectTO = (VolumeObjectTO)data; + + if ((volumeObjectTO.getBytesReadRate() != null) && (volumeObjectTO.getBytesReadRate() > 0)) + disk.setBytesReadRate(volumeObjectTO.getBytesReadRate()); + if ((volumeObjectTO.getBytesWriteRate() != null) && (volumeObjectTO.getBytesWriteRate() > 0)) + disk.setBytesWriteRate(volumeObjectTO.getBytesWriteRate()); + if ((volumeObjectTO.getIopsReadRate() != null) && (volumeObjectTO.getIopsReadRate() > 0)) + disk.setIopsReadRate(volumeObjectTO.getIopsReadRate()); + if ((volumeObjectTO.getIopsWriteRate() != null) && (volumeObjectTO.getIopsWriteRate() > 0)) + disk.setIopsWriteRate(volumeObjectTO.getIopsWriteRate()); + vm.getDevices().addDevice(disk); } @@ -3515,12 +3475,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; @@ -3530,16 +3492,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( @@ -3568,7 +3520,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; @@ -3635,7 +3587,7 @@ ServerResource { protected synchronized String attachOrDetachDisk(Connect conn, boolean attach, String vmName, KVMPhysicalDisk attachingDisk, - int devId) throws LibvirtException, InternalErrorException { + int devId, Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) throws LibvirtException, InternalErrorException { List disks = null; Domain dm = null; DiskDef diskdef = null; @@ -3675,6 +3627,14 @@ ServerResource { diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, DiskDef.diskBus.VIRTIO); } + if ((bytesReadRate != null) && (bytesReadRate > 0)) + diskdef.setBytesReadRate(bytesReadRate); + if ((bytesWriteRate != null) && (bytesWriteRate > 0)) + diskdef.setBytesWriteRate(bytesWriteRate); + if ((iopsReadRate != null) && (iopsReadRate > 0)) + diskdef.setIopsReadRate(iopsReadRate); + if ((iopsWriteRate != null) && (iopsWriteRate > 0)) + diskdef.setIopsWriteRate(iopsWriteRate); } String xml = diskdef.toString(); @@ -4383,6 +4343,7 @@ ServerResource { return parser.getEmulator(); } + private String getGuestType(Connect conn, String vmName) { LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); Domain dm = null; @@ -4441,14 +4402,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; @@ -4482,7 +4435,7 @@ ServerResource { } } - private Domain getDomain(Connect conn, String vmName) + public Domain getDomain(Connect conn, String vmName) throws LibvirtException { return conn .domainLookupByName(vmName); @@ -4510,7 +4463,7 @@ ServerResource { } } - protected List getDisks(Connect conn, String vmName) { + public List getDisks(Connect conn, String vmName) { LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); Domain dm = null; try { @@ -4539,38 +4492,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 List getVmDiskStat(Connect conn, String vmName) throws LibvirtException { 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/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java index b8645e1664a..a283768da41 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java @@ -105,6 +105,31 @@ public class LibvirtDomainXMLParser { DiskDef.diskBus.valueOf(bus.toUpperCase())); } } + + NodeList iotune = disk.getElementsByTagName("iotune"); + if ((iotune != null) && (iotune.getLength() !=0)) { + String bytesReadRateStr = getTagValue("read_bytes_sec", (Element)iotune.item(0)); + if (bytesReadRateStr != null) { + Long bytesReadRate = Long.parseLong(bytesReadRateStr); + def.setBytesReadRate(bytesReadRate); + } + String bytesWriteRateStr = getTagValue("write_bytes_sec", (Element)iotune.item(0)); + if (bytesWriteRateStr != null) { + Long bytesWriteRate = Long.parseLong(bytesWriteRateStr); + def.setBytesWriteRate(bytesWriteRate); + } + String iopsReadRateStr = getTagValue("read_iops_sec", (Element)iotune.item(0)); + if (iopsReadRateStr != null) { + Long iopsReadRate = Long.parseLong(iopsReadRateStr); + def.setIopsReadRate(iopsReadRate); + } + String iopsWriteRateStr = getTagValue("write_iops_sec", (Element)iotune.item(0)); + if (iopsWriteRateStr != null) { + Long iopsWriteRate = Long.parseLong(iopsWriteRateStr); + def.setIopsWriteRate(iopsWriteRate); + } + } + diskDefs.add(def); } @@ -117,18 +142,25 @@ public class LibvirtDomainXMLParser { String dev = getAttrValue("target", "dev", nic); String model = getAttrValue("model", "type", nic); InterfaceDef def = new InterfaceDef(); - + NodeList bandwidth = nic.getElementsByTagName("bandwidth"); + Integer networkRateKBps = 0; + if ((bandwidth != null) && (bandwidth.getLength() !=0)) { + Integer inbound = Integer.valueOf(getAttrValue("inbound", "average", (Element)bandwidth.item(0))); + Integer outbound = Integer.valueOf(getAttrValue("outbound", "average", (Element)bandwidth.item(0))); + if (inbound == outbound) + networkRateKBps = inbound; + } if (type.equalsIgnoreCase("network")) { String network = getAttrValue("source", "network", nic); def.defPrivateNet(network, dev, mac, - nicModel.valueOf(model.toUpperCase())); + nicModel.valueOf(model.toUpperCase()), networkRateKBps); } else if (type.equalsIgnoreCase("bridge")) { String bridge = getAttrValue("source", "bridge", nic); def.defBridgeNet(bridge, dev, mac, - nicModel.valueOf(model.toUpperCase())); + nicModel.valueOf(model.toUpperCase()), networkRateKBps); } else if (type.equalsIgnoreCase("ethernet")) { String scriptPath = getAttrValue("script", "path", nic); - def.defEthernet(dev, mac, nicModel.valueOf(model.toUpperCase()), scriptPath); + def.defEthernet(dev, mac, nicModel.valueOf(model.toUpperCase()), scriptPath, networkRateKBps); } interfaces.add(def); } 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 e91e3477b0b..51208702169 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 @@ -24,6 +24,8 @@ import java.util.UUID; public class LibvirtVMDef { private String _hvsType; + private static long _libvirtVersion; + private static long _qemuVersion; private String _domName; private String _domUUID; private String _desc; @@ -354,7 +356,7 @@ public class LibvirtVMDef { } public static class DiskDef { - enum deviceType { + public enum deviceType { FLOPPY("floppy"), DISK("disk"), CDROM("cdrom"); String _type; @@ -396,7 +398,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 +413,7 @@ public class LibvirtVMDef { } } - enum diskFmtType { + public enum diskFmtType { RAW("raw"), QCOW2("qcow2"); String _fmtType; @@ -439,6 +441,10 @@ public class LibvirtVMDef { private boolean _readonly = false; private boolean _shareable = false; private boolean _deferAttach = false; + private Long _bytesReadRate; + private Long _bytesWriteRate; + private Long _iopsReadRate; + private Long _iopsWriteRate; public void setDeviceType(deviceType deviceType) { _deviceType = deviceType; @@ -584,6 +590,22 @@ public class LibvirtVMDef { return suffix - 'a'; } + public void setBytesReadRate(Long bytesReadRate) { + _bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + _bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + _iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + _iopsWriteRate = iopsWriteRate; + } + @Override public String toString() { StringBuilder diskBuilder = new StringBuilder(); @@ -627,6 +649,22 @@ public class LibvirtVMDef { diskBuilder.append(" bus='" + _bus + "'"); } diskBuilder.append("/>\n"); + + if ((_deviceType != deviceType.CDROM) && (_libvirtVersion >= 9008) && (_qemuVersion >= 1001000) + && (((_bytesReadRate != null) && (_bytesReadRate > 0)) || ((_bytesWriteRate != null) && (_bytesWriteRate > 0)) + || ((_iopsReadRate != null) && (_iopsReadRate > 0)) || ((_iopsWriteRate != null) && (_iopsWriteRate > 0)) )) { // not CDROM, from libvirt 0.9.8 and QEMU 1.1.0 + diskBuilder.append("\n"); + if ((_bytesReadRate != null) && (_bytesReadRate > 0)) + diskBuilder.append("" + _bytesReadRate + "\n"); + if ((_bytesWriteRate != null) && (_bytesWriteRate > 0)) + diskBuilder.append("" + _bytesWriteRate + "\n"); + if ((_iopsReadRate != null) && (_iopsReadRate > 0)) + diskBuilder.append("" + _iopsReadRate + "\n"); + if ((_iopsWriteRate != null) && (_iopsWriteRate > 0)) + diskBuilder.append("" + _iopsWriteRate + "\n"); + diskBuilder.append("\n"); + } + diskBuilder.append("\n"); return diskBuilder.toString(); } @@ -679,45 +717,69 @@ public class LibvirtVMDef { private String _ipAddr; private String _scriptPath; private nicModel _model; + private Integer _networkRateKBps; private String _virtualPortType; private String _virtualPortInterfaceId; private int _vlanTag = -1; public void defBridgeNet(String brName, String targetBrName, String macAddr, nicModel model) { + defBridgeNet(brName, targetBrName, macAddr, model, 0); + } + + public void defBridgeNet(String brName, String targetBrName, + String macAddr, nicModel model, Integer networkRateKBps) { _netType = guestNetType.BRIDGE; _sourceName = brName; _networkName = targetBrName; _macAddr = macAddr; _model = model; + _networkRateKBps = networkRateKBps; } public void defDirectNet(String sourceName, String targetName, String macAddr, nicModel model, String sourceMode) { + defDirectNet(sourceName, targetName, macAddr, model, sourceMode, 0); + } + + public void defDirectNet(String sourceName, String targetName, + String macAddr, nicModel model, String sourceMode, Integer networkRateKBps) { _netType = guestNetType.DIRECT; _netSourceMode = sourceMode; _sourceName = sourceName; _networkName = targetName; _macAddr = macAddr; _model = model; + _networkRateKBps = networkRateKBps; } public void defPrivateNet(String networkName, String targetName, String macAddr, nicModel model) { + defPrivateNet(networkName, targetName, macAddr, model, 0); + } + + public void defPrivateNet(String networkName, String targetName, + String macAddr, nicModel model, Integer networkRateKBps) { _netType = guestNetType.NETWORK; _sourceName = networkName; _networkName = targetName; _macAddr = macAddr; _model = model; + _networkRateKBps = networkRateKBps; } public void defEthernet(String targetName, String macAddr, nicModel model, String scriptPath) { + defEthernet(targetName, macAddr, model, scriptPath, 0); + } + + public void defEthernet(String targetName, String macAddr, nicModel model, String scriptPath, Integer networkRateKBps) { _netType = guestNetType.ETHERNET; _networkName = targetName; _sourceName = targetName; _macAddr = macAddr; _model = model; _scriptPath = scriptPath; + _networkRateKBps = networkRateKBps; } public void defEthernet(String targetName, String macAddr, nicModel model) { @@ -796,6 +858,12 @@ public class LibvirtVMDef { if (_model != null) { netBuilder.append("\n"); } + if ((_libvirtVersion >= 9004) && (_networkRateKBps > 0)) { // supported from libvirt 0.9.4 + netBuilder.append("\n"); + netBuilder.append("\n"); + netBuilder.append("\n"); + netBuilder.append("\n"); + } if (_scriptPath != null) { netBuilder.append("