diff --git a/agent/pom.xml b/agent/pom.xml
index 7b00a93963f..14133226053 100644
--- a/agent/pom.xml
+++ b/agent/pom.xml
@@ -36,6 +36,10 @@
cloud-utils
${project.version}
+
+ commons-io
+ commons-io
+
commons-daemon
commons-daemon
diff --git a/agent/src/com/cloud/agent/Agent.java b/agent/src/com/cloud/agent/Agent.java
index c713e459262..c4f17b24ae7 100755
--- a/agent/src/com/cloud/agent/Agent.java
+++ b/agent/src/com/cloud/agent/Agent.java
@@ -45,7 +45,6 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.CronCommand;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.ModifySshKeysCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.ShutdownCommand;
diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java
index 42adac07165..900a13f4ab1 100644
--- a/agent/src/com/cloud/agent/AgentShell.java
+++ b/agent/src/com/cloud/agent/AgentShell.java
@@ -20,6 +20,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
@@ -36,7 +37,8 @@ import javax.naming.ConfigurationException;
import org.apache.commons.daemon.Daemon;
import org.apache.commons.daemon.DaemonContext;
import org.apache.commons.daemon.DaemonInitException;
-import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.math.NumberUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
@@ -55,7 +57,6 @@ import com.cloud.utils.exception.CloudRuntimeException;
public class AgentShell implements IAgentShell, Daemon {
private static final Logger s_logger = Logger.getLogger(AgentShell.class
.getName());
- private static final MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager();
private final Properties _properties = new Properties();
private final Map _cmdLineProperties = new HashMap();
@@ -166,7 +167,7 @@ public class AgentShell implements IAgentShell, Daemon {
_storage.persist(name, value);
}
- private void loadProperties() throws ConfigurationException {
+ void loadProperties() throws ConfigurationException {
final File file = PropertiesUtil.findConfigFile("agent.properties");
if (file == null) {
throw new ConfigurationException("Unable to find agent.properties.");
@@ -174,14 +175,18 @@ public class AgentShell implements IAgentShell, Daemon {
s_logger.info("agent.properties found at " + file.getAbsolutePath());
+ InputStream propertiesStream = null;
try {
- _properties.load(new FileInputStream(file));
+ propertiesStream = new FileInputStream(file);
+ _properties.load(propertiesStream);
} catch (final FileNotFoundException ex) {
throw new CloudRuntimeException("Cannot find the file: "
+ file.getAbsolutePath(), ex);
} catch (final IOException ex) {
throw new CloudRuntimeException("IOException in reading "
+ file.getAbsolutePath(), ex);
+ } finally {
+ IOUtils.closeQuietly(propertiesStream);
}
}
@@ -193,30 +198,32 @@ public class AgentShell implements IAgentShell, Daemon {
String zone = null;
String pod = null;
String guid = null;
- for (int i = 0; i < args.length; i++) {
- final String[] tokens = args[i].split("=");
+ for (String param : args) {
+ final String[] tokens = param.split("=");
if (tokens.length != 2) {
- System.out.println("Invalid Parameter: " + args[i]);
+ System.out.println("Invalid Parameter: " + param);
continue;
}
+ final String paramName = tokens[0];
+ final String paramValue = tokens[1];
// save command line properties
- _cmdLineProperties.put(tokens[0], tokens[1]);
+ _cmdLineProperties.put(paramName, paramValue);
- if (tokens[0].equalsIgnoreCase("port")) {
- port = tokens[1];
- } else if (tokens[0].equalsIgnoreCase("threads") || tokens[0].equalsIgnoreCase("workers")) {
- workers = tokens[1];
- } else if (tokens[0].equalsIgnoreCase("host")) {
- host = tokens[1];
- } else if (tokens[0].equalsIgnoreCase("zone")) {
- zone = tokens[1];
- } else if (tokens[0].equalsIgnoreCase("pod")) {
- pod = tokens[1];
- } else if (tokens[0].equalsIgnoreCase("guid")) {
- guid = tokens[1];
- } else if (tokens[0].equalsIgnoreCase("eth1ip")) {
- _privateIp = tokens[1];
+ if (paramName.equalsIgnoreCase("port")) {
+ port = paramValue;
+ } else if (paramName.equalsIgnoreCase("threads") || paramName.equalsIgnoreCase("workers")) {
+ workers = paramValue;
+ } else if (paramName.equalsIgnoreCase("host")) {
+ host = paramValue;
+ } else if (paramName.equalsIgnoreCase("zone")) {
+ zone = paramValue;
+ } else if (paramName.equalsIgnoreCase("pod")) {
+ pod = paramValue;
+ } else if (paramName.equalsIgnoreCase("guid")) {
+ guid = paramValue;
+ } else if (paramName.equalsIgnoreCase("eth1ip")) {
+ _privateIp = paramValue;
}
}
@@ -224,16 +231,16 @@ public class AgentShell implements IAgentShell, Daemon {
port = getProperty(null, "port");
}
- _port = NumbersUtil.parseInt(port, 8250);
+ _port = NumberUtils.toInt(port, 8250);
- _proxyPort = NumbersUtil.parseInt(
+ _proxyPort = NumberUtils.toInt(
getProperty(null, "consoleproxy.httpListenPort"), 443);
if (workers == null) {
workers = getProperty(null, "workers");
}
- _workers = NumbersUtil.parseInt(workers, 5);
+ _workers = NumberUtils.toInt(workers, 5);
if (host == null) {
host = getProperty(null, "host");
@@ -303,7 +310,7 @@ public class AgentShell implements IAgentShell, Daemon {
// For KVM agent, do it specially here
File file = new File("/etc/cloudstack/agent/log4j-cloud.xml");
- if(file == null || !file.exists()) {
+ if(!file.exists()) {
file = PropertiesUtil.findConfigFile("log4j-cloud.xml");
}
DOMConfigurator.configureAndWatch(file.getAbsolutePath());
diff --git a/agent/test/com/cloud/agent/AgentShellTest.java b/agent/test/com/cloud/agent/AgentShellTest.java
new file mode 100644
index 00000000000..d92accbd7e8
--- /dev/null
+++ b/agent/test/com/cloud/agent/AgentShellTest.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 com.cloud.agent;
+
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class AgentShellTest {
+ @Test
+ public void parseCommand() throws ConfigurationException {
+ AgentShell shell = new AgentShell();
+ UUID anyUuid = UUID.randomUUID();
+ shell.parseCommand(new String[] { "port=55555", "threads=4",
+ "host=localhost", "pod=pod1", "guid=" + anyUuid, "zone=zone1" });
+ Assert.assertEquals(55555, shell.getPort());
+ Assert.assertEquals(4, shell.getWorkers());
+ Assert.assertEquals("localhost", shell.getHost());
+ Assert.assertEquals(anyUuid.toString(), shell.getGuid());
+ Assert.assertEquals("pod1", shell.getPod());
+ Assert.assertEquals("zone1", shell.getZone());
+ }
+ @Test
+ public void loadProperties() throws ConfigurationException {
+ AgentShell shell = new AgentShell();
+ shell.loadProperties();
+ Assert.assertNotNull(shell.getProperties());
+ Assert.assertFalse(shell.getProperties().entrySet().isEmpty());
+ }
+}
diff --git a/api/resources/META-INF/cloudstack/api-planner/module.properties b/api/resources/META-INF/cloudstack/api-planner/module.properties
new file mode 100644
index 00000000000..8eed8791149
--- /dev/null
+++ b/api/resources/META-INF/cloudstack/api-planner/module.properties
@@ -0,0 +1,18 @@
+# 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.
+name=api-planner
+parent=planner
\ No newline at end of file
diff --git a/api/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml b/api/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml
new file mode 100644
index 00000000000..2fd34a8ee0a
--- /dev/null
+++ b/api/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
diff --git a/api/src/com/cloud/exception/ConcurrentOperationException.java b/api/src/com/cloud/exception/ConcurrentOperationException.java
index cfe6ba3fa0a..018dba55f2e 100644
--- a/api/src/com/cloud/exception/ConcurrentOperationException.java
+++ b/api/src/com/cloud/exception/ConcurrentOperationException.java
@@ -17,8 +17,9 @@
package com.cloud.exception;
import com.cloud.utils.SerialVersionUID;
+import com.cloud.utils.exception.CloudRuntimeException;
-public class ConcurrentOperationException extends CloudException {
+public class ConcurrentOperationException extends CloudRuntimeException {
private static final long serialVersionUID = SerialVersionUID.ConcurrentOperationException;
diff --git a/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java b/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java
index 4950ed92cab..b9233755249 100644
--- a/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java
+++ b/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java
@@ -19,7 +19,6 @@ package com.cloud.network.element;
import java.util.List;
import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.VpnUser;
import com.cloud.utils.component.Adapter;
@@ -27,7 +26,7 @@ import com.cloud.utils.component.Adapter;
public interface RemoteAccessVPNServiceProvider extends Adapter {
String[] applyVpnUsers(RemoteAccessVpn vpn, List extends VpnUser> users) throws ResourceUnavailableException;
- boolean startVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
+ boolean startVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException;
- boolean stopVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
+ boolean stopVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException;
}
diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java
index 6c5573e0368..749dae32fc9 100644
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ b/api/src/com/cloud/offering/NetworkOffering.java
@@ -130,4 +130,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
boolean getEgressDefaultPolicy();
Integer getConcurrentConnections();
+
+ boolean isKeepAliveEnabled();
}
diff --git a/api/src/com/cloud/vm/VmDetailConstants.java b/api/src/com/cloud/vm/VmDetailConstants.java
index 5ff3ce02fe4..87f4b5dc5de 100644
--- a/api/src/com/cloud/vm/VmDetailConstants.java
+++ b/api/src/com/cloud/vm/VmDetailConstants.java
@@ -21,4 +21,5 @@ public interface VmDetailConstants {
public static final String NIC_ADAPTER = "nicAdapter";
public static final String ROOK_DISK_CONTROLLER = "rootDiskController";
public static final String NESTED_VIRTUALIZATION_FLAG = "nestedVirtualizationFlag";
+ public static final String HYPERVISOR_TOOLS_VERSION = "hypervisortoolsversion";
}
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index e2f225d5fcc..dbf668598dc 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -34,6 +34,7 @@ public class ApiConstants {
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 CAN_REVERT = "canrevert";
public static final String CERTIFICATE = "certificate";
public static final String PRIVATE_KEY = "privatekey";
public static final String DOMAIN_SUFFIX = "domainsuffix";
@@ -142,6 +143,7 @@ public class ApiConstants {
public static final String MAX_SNAPS = "maxsnaps";
public static final String MEMORY = "memory";
public static final String MODE = "mode";
+ public static final String KEEPALIVE_ENABLED = "keepaliveenabled";
public static final String NAME = "name";
public static final String METHOD_NAME = "methodname";
public static final String NETWORK_DOMAIN = "networkdomain";
@@ -186,6 +188,7 @@ public class ApiConstants {
public static final String REQUIRES_HVM = "requireshvm";
public static final String RESOURCE_TYPE = "resourcetype";
public static final String RESPONSE = "response";
+ public static final String REVERTABLE = "revertable";
public static final String QUERY_FILTER = "queryfilter";
public static final String SCHEDULE = "schedule";
public static final String SCOPE = "scope";
@@ -248,7 +251,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_NAME = "zonename";
public static final String NETWORK_TYPE = "networktype";
public static final String PAGE = "page";
public static final String PAGE_SIZE = "pagesize";
@@ -519,6 +522,8 @@ public class ApiConstants {
public static final String MAX_CONNECTIONS = "maxconnections";
public static final String SERVICE_STATE = "servicestate";
public static final String RESOURCE_TAGS = "resourcetags";
+ public static final String EXPUNGE = "expunge";
+
public enum HostDetails {
all, capacity, events, stats, min;
}
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 bdad904c1dd..7296d5315d8 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
@@ -96,12 +96,15 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
private Boolean isPersistent;
@Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, since="4.2.0", description="Network offering details in key/value pairs." +
- " Supported keys are internallbprovider/publiclbprovider with service provider as a value")
+ " 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;
+ @Parameter(name=ApiConstants.KEEPALIVE_ENABLED, type=CommandType.BOOLEAN, required=false, description="if true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.")
+ private Boolean keepAliveEnabled;
+
@Parameter(name=ApiConstants.MAX_CONNECTIONS, type=CommandType.INTEGER, description="maximum number of concurrent connections supported by the network offering")
private Integer maxConnections;
@@ -175,6 +178,10 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
return egressDefaultPolicy;
}
+ public Boolean getKeepAliveEnabled() {
+ return keepAliveEnabled;
+ }
+
public Integer getMaxconnections() {
return maxConnections;
}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
index c9c4c8ad3b4..f9bdadb4547 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
@@ -57,6 +57,9 @@ public class UpdateNetworkOfferingCmd extends BaseCmd {
@Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="update state for the network offering")
private String state;
+ @Parameter(name=ApiConstants.KEEPALIVE_ENABLED, type=CommandType.BOOLEAN, required=false, description="if true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.")
+ private Boolean keepAliveEnabled;
+
@Parameter(name=ApiConstants.MAX_CONNECTIONS, type=CommandType.INTEGER, description="maximum number of concurrent connections supported by the network offering")
private Integer maxConnections;
@@ -91,6 +94,10 @@ public class UpdateNetworkOfferingCmd extends BaseCmd {
public Integer getMaxconnections() {
return maxConnections;
}
+
+ public Boolean getKeepAliveEnabled() {
+ return keepAliveEnabled;
+ }
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java
index e0cd7133e11..a44b76828fb 100644
--- a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java
@@ -153,9 +153,7 @@ public class UpdateNetworkCmd extends BaseAsyncCmd {
@Override
public String getEventDescription() {
-
-
- StringBuffer eventMsg = new StringBuffer("Updating network: " + getId());
+ StringBuilder eventMsg = new StringBuilder("Updating network: " + getId());
if (getNetworkOfferingId() != null) {
Network network = _networkService.getNetwork(getId());
if (network == null) {
diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java b/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java
index 6f1a081da12..e36bd73263b 100644
--- a/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java
@@ -20,16 +20,16 @@ import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.CreateSSHKeyPairResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.SSHKeyPairResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import com.cloud.user.SSHKeyPair;
-@APICommand(name = "createSSHKeyPair", description="Create a new keypair and returns the private key", responseObject=SSHKeyPairResponse.class)
+@APICommand(name = "createSSHKeyPair", description="Create a new keypair and returns the private key", responseObject=CreateSSHKeyPairResponse.class)
public class CreateSSHKeyPairCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateSSHKeyPairCmd.class.getName());
private static final String s_name = "createsshkeypairresponse";
@@ -91,7 +91,7 @@ public class CreateSSHKeyPairCmd extends BaseCmd {
@Override
public void execute() {
SSHKeyPair r = _mgr.createSSHKeyPair(this);
- SSHKeyPairResponse response = new SSHKeyPairResponse(r.getName(), r.getFingerprint(), r.getPrivateKey());
+ CreateSSHKeyPairResponse response = new CreateSSHKeyPairResponse(r.getName(), r.getFingerprint(), r.getPrivateKey());
response.setResponseName(getCommandName());
response.setObjectName("keypair");
this.setResponseObject(response);
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
index 06959c15e75..b3e8d1f83fe 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
@@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.api.command.user.vm;
+import java.util.List;
+
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.ApiConstants;
@@ -25,13 +27,11 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.context.CallContext;
-
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
@@ -48,7 +48,12 @@ public class DestroyVMCmd extends BaseAsyncCmd {
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
required=true, description="The ID of the virtual machine")
private Long id;
-
+
+
+ @Parameter(name=ApiConstants.EXPUNGE, type=CommandType.BOOLEAN,
+ description="If true is passed, the vm is expunged immediately. False by default. Parameter can be passed to the call by ROOT/Domain admin only", since="4.2.1")
+ private Boolean expunge;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -56,6 +61,13 @@ public class DestroyVMCmd extends BaseAsyncCmd {
public Long getId() {
return id;
}
+
+ public boolean getExpunge() {
+ if (expunge == null) {
+ return false;
+ }
+ return expunge;
+ }
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
@@ -97,11 +109,14 @@ public class DestroyVMCmd extends BaseAsyncCmd {
@Override
public void execute() throws ResourceUnavailableException, ConcurrentOperationException{
CallContext.current().setEventDetails("Vm Id: "+getId());
- UserVm result;
- result = _userVmService.destroyVm(this);
+ UserVm result = _userVmService.destroyVm(this);
+ UserVmResponse response = new UserVmResponse();
if (result != null) {
- UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+ List responses = _responseGenerator.createUserVmResponse("virtualmachine", result);
+ if (responses != null && !responses.isEmpty()) {
+ response = responses.get(0);
+ }
response.setResponseName("virtualmachine");
this.setResponseObject(response);
} else {
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java
index 8be70f348d0..fefa926ebd3 100644
--- a/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java
@@ -16,32 +16,21 @@
// under the License.
package org.apache.cloudstack.api.command.user.volume;
-import com.cloud.server.ResourceTag;
-
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-
-import java.util.*;
+import com.cloud.server.ResourceTag;
@APICommand(name = "removeResourceDetail", description="Removes detail for the Resource.", responseObject=SuccessResponse.class)
public class RemoveResourceDetailCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(RemoveResourceDetailCmd.class.getName());
- private static final String s_name = "RemoveResourceDetailresponse";
+ private static final String s_name = "removeresourcedetailresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java
index b247e0f4528..d4e3a6c1643 100644
--- a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java
@@ -114,8 +114,8 @@ public class UpdateVolumeCmd extends BaseAsyncCmd {
@Override
public String getEventDescription() {
- StringBuffer desc = new StringBuffer();
- desc.append(" with");
+ StringBuilder desc = new StringBuilder("Updating volume: ");
+ desc.append(getId()).append(" with");
if (getPath() != null) {
desc.append(" path " + getPath());
}
@@ -126,7 +126,7 @@ public class UpdateVolumeCmd extends BaseAsyncCmd {
if (getState() != null) {
desc.append(", state " + getState());
}
- return "Updating volume: " + getId() + desc.toString();
+ return desc.toString();
}
@Override
diff --git a/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java b/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java
new file mode 100644
index 00000000000..e247fb4dcbc
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.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.api.response;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class CreateSSHKeyPairResponse extends SSHKeyPairResponse {
+
+ @SerializedName("privatekey") @Param(description="Private key")
+ private String privateKey;
+
+ public CreateSSHKeyPairResponse() {}
+
+ public CreateSSHKeyPairResponse(String name, String fingerprint, String privateKey) {
+ super(name, fingerprint);
+ this.privateKey = privateKey;
+ }
+
+ public String getPrivateKey() {
+ return privateKey;
+ }
+
+ public void setPrivateKey(String privateKey) {
+ this.privateKey = privateKey;
+ }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java b/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java
index 2791853d4a2..e102bab0394 100644
--- a/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java
@@ -30,19 +30,11 @@ public class SSHKeyPairResponse extends BaseResponse {
@SerializedName("fingerprint") @Param(description="Fingerprint of the public key")
private String fingerprint;
- @SerializedName("privatekey") @Param(description="Private key")
- private String privateKey;
-
public SSHKeyPairResponse() {}
public SSHKeyPairResponse(String name, String fingerprint) {
- this(name, fingerprint, null);
- }
-
- public SSHKeyPairResponse(String name, String fingerprint, String privateKey) {
this.name = name;
this.fingerprint = fingerprint;
- this.privateKey = privateKey;
}
public String getName() {
@@ -61,12 +53,4 @@ public class SSHKeyPairResponse extends BaseResponse {
this.fingerprint = fingerprint;
}
- public String getPrivateKey() {
- return privateKey;
- }
-
- public void setPrivateKey(String privateKey) {
- this.privateKey = privateKey;
- }
-
}
diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java
index e9cb109bf31..7c2b4a99770 100644
--- a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java
@@ -26,18 +26,8 @@ import org.apache.cloudstack.api.EntityReference;
import com.cloud.serializer.Param;
import com.cloud.storage.Snapshot;
import com.google.gson.annotations.SerializedName;
-import com.cloud.serializer.Param;
-import com.cloud.storage.Snapshot;
-import com.google.gson.annotations.SerializedName;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.EntityReference;
-
-import java.util.Date;
-import java.util.List;
@EntityReference(value=Snapshot.class)
-@SuppressWarnings("unused")
public class SnapshotResponse extends BaseResponse implements ControlledEntityResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "ID of the snapshot")
@@ -100,6 +90,9 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class)
private List tags;
+ @SerializedName(ApiConstants.REVERTABLE)
+ @Param(description="indicates whether the underlying storage supports reverting the volume to this snapshot")
+ private boolean revertable;
@Override
public String getObjectId() {
@@ -118,6 +111,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe
return accountName;
}
+ @Override
public void setAccountName(String accountName) {
this.accountName = accountName;
}
@@ -131,6 +125,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe
this.domainId = domainId;
}
+ @Override
public void setDomainName(String domainName) {
this.domainName = domainName;
}
@@ -180,8 +175,16 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe
public void setZoneId(String zoneId) {
this.zoneId = zoneId;
}
-
+
public void setTags(List tags) {
this.tags = tags;
}
+
+ public boolean isRevertable() {
+ return revertable;
+ }
+
+ public void setRevertable(boolean revertable) {
+ this.revertable = revertable;
+ }
}
diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
index d9bb2a976ee..9a7f91c70f6 100644
--- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
@@ -18,6 +18,7 @@ package org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.LinkedHashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
@@ -177,6 +178,9 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with vm", responseObject = ResourceTagResponse.class)
private Set tags;
+
+ @SerializedName(ApiConstants.DETAILS) @Param(description="Template details in key/value pairs.", since="4.2.1")
+ private Map details;
@SerializedName(ApiConstants.SSH_KEYPAIR) @Param(description="ssh key-pair")
private String keyPairName;
@@ -653,5 +657,8 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
public void setServiceState(String state) {
this.serviceState = state;
}
-
+
+ public void setDetails(Map details) {
+ this.details = details;
+ }
}
diff --git a/api/src/org/apache/cloudstack/context/CallContext.java b/api/src/org/apache/cloudstack/context/CallContext.java
index a9867d3bb70..73bf3556408 100644
--- a/api/src/org/apache/cloudstack/context/CallContext.java
+++ b/api/src/org/apache/cloudstack/context/CallContext.java
@@ -57,7 +57,7 @@ public class CallContext {
private User user;
private final Map