diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java b/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java index a2515056be1..838f0877918 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java @@ -19,6 +19,8 @@ package com.cloud.agent.resource.virtualnetwork; +import org.joda.time.Duration; + public class VRScripts { public final static String CONFIG_PERSIST_LOCATION = "/var/cache/cloud/"; public final static String IP_ASSOCIATION_CONFIG = "ip_associations.json"; @@ -40,7 +42,8 @@ public class VRScripts { public static final String LOAD_BALANCER_CONFIG = "load_balancer.json"; public final static String CONFIG_CACHE_LOCATION = "/var/cache/cloud/"; - public final static int DEFAULT_EXECUTEINVR_TIMEOUT = 120; //Seconds + public final static Duration VR_SCRIPT_EXEC_TIMEOUT = Duration.standardMinutes(10); + public final static Duration CONNECTION_TIMEOUT = Duration.standardMinutes(1); // New scripts for use with chef public static final String UPDATE_CONFIG = "update_config.py"; diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java index f6a1694c558..6501292b82b 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java @@ -19,13 +19,14 @@ package com.cloud.agent.resource.virtualnetwork; +import org.joda.time.Duration; + import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.utils.ExecutionResult; public interface VirtualRouterDeployer { ExecutionResult executeInVR(String routerIp, String script, String args); - /* timeout in seconds */ - ExecutionResult executeInVR(String routerIp, String script, String args, int timeout); + ExecutionResult executeInVR(String routerIp, String script, String args, Duration timeout); ExecutionResult createFileInVR(String routerIp, String path, String filename, String content); ExecutionResult prepareCommand(NetworkElementCommand cmd); ExecutionResult cleanupCommand(NetworkElementCommand cmd); diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index f3edc696759..87a38d3e39f 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -22,6 +22,7 @@ package com.cloud.agent.resource.virtualnetwork; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SocketChannel; +import org.joda.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -73,7 +74,7 @@ public class VirtualRoutingResource { private int _sleep; private int _retry; private int _port; - private int _eachTimeout; + private Duration _eachTimeout; private String _cfgVersion = "1.0"; @@ -153,10 +154,10 @@ public class VirtualRoutingResource { } private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c) { - return applyConfigToVR(routerAccessIp, c, VRScripts.DEFAULT_EXECUTEINVR_TIMEOUT); + return applyConfigToVR(routerAccessIp, c, VRScripts.VR_SCRIPT_EXEC_TIMEOUT); } - private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c, int timeout) { + private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c, Duration timeout) { if (c instanceof FileConfigItem) { FileConfigItem configItem = (FileConfigItem)c; return _vrDeployer.createFileInVR(routerAccessIp, configItem.getFilePath(), configItem.getFileName(), configItem.getFileContents()); @@ -271,7 +272,7 @@ public class VirtualRoutingResource { _port = NumbersUtil.parseInt(value, 3922); value = (String)params.get("router.aggregation.command.each.timeout"); - _eachTimeout = NumbersUtil.parseInt(value, 3); + _eachTimeout = Duration.standardSeconds(NumbersUtil.parseInt(value, 10)); if (_vrDeployer == null) { throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!"); @@ -374,9 +375,9 @@ public class VirtualRoutingResource { FileConfigItem fileConfigItem = new FileConfigItem(VRScripts.CONFIG_CACHE_LOCATION, cfgFileName, sb.toString()); ScriptConfigItem scriptConfigItem = new ScriptConfigItem(VRScripts.VR_CFG, "-c " + VRScripts.CONFIG_CACHE_LOCATION + cfgFileName); // 120s is the minimal timeout - int timeout = answerCounts * _eachTimeout; - if (timeout < 120) { - timeout = 120; + Duration timeout = _eachTimeout.withDurationAdded(_eachTimeout.getStandardSeconds(), answerCounts); + if (timeout.isShorterThan(VRScripts.VR_SCRIPT_EXEC_TIMEOUT)) { + timeout = VRScripts.VR_SCRIPT_EXEC_TIMEOUT; } ExecutionResult result = applyConfigToVR(cmd.getRouterAccessIp(), fileConfigItem); diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java index 6b5f1d1baf5..6405037dd0f 100644 --- a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java +++ b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java @@ -31,6 +31,7 @@ import java.util.UUID; import javax.naming.ConfigurationException; +import org.joda.time.Duration; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -97,11 +98,11 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer { @Override public ExecutionResult executeInVR(final String routerIp, final String script, final String args) { - return executeInVR(routerIp, script, args, 60); + return executeInVR(routerIp, script, args, Duration.standardSeconds(60L)); } @Override - public ExecutionResult executeInVR(final String routerIp, final String script, final String args, final int timeout) { + public ExecutionResult executeInVR(final String routerIp, final String script, final String args, final Duration timeout) { assertEquals(routerIp, ROUTERIP); verifyCommand(_currentCmd, script, args); return new ExecutionResult(true, null); diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java index 5b5ec57a889..862cc30a2e5 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java @@ -32,6 +32,7 @@ import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import org.joda.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -622,11 +623,11 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S @Override public ExecutionResult executeInVR(final String routerIP, final String script, final String args) { - return executeInVR(routerIP, script, args, 120); + return executeInVR(routerIP, script, args, Duration.standardSeconds(120L)); } @Override - public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final int timeout) { + public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final Duration timeout) { Pair result; //TODO: Password should be masked, cannot output to log directly @@ -635,8 +636,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } try { - result = SshHelper.sshExecute(routerIP, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args, - 60000, 60000, timeout * 1000); + result = SshHelper.sshExecute(routerIP, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args, VRScripts.CONNECTION_TIMEOUT, + VRScripts.CONNECTION_TIMEOUT, timeout); } catch (final Exception e) { final String msg = "Command failed due to " + e ; s_logger.error(msg); 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 2b9aa71cf2f..7e2b1bf8666 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -25,6 +25,7 @@ import java.io.Reader; import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; +import org.joda.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -191,7 +192,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private String _clusterId; private long _hvVersion; - private int _timeout; + private Duration _timeout; private static final int NUMMEMSTATS =2; private KVMHAMonitor _monitor; @@ -279,12 +280,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv @Override public ExecutionResult executeInVR(final String routerIp, final String script, final String args) { - return executeInVR(routerIp, script, args, _timeout / 1000); + return executeInVR(routerIp, script, args, _timeout); } @Override - public ExecutionResult executeInVR(final String routerIp, final String script, final String args, final int timeout) { - final Script command = new Script(_routerProxyPath, timeout * 1000, s_logger); + public ExecutionResult executeInVR(final String routerIp, final String script, final String args, final Duration timeout) { + final Script command = new Script(_routerProxyPath, timeout, s_logger); final AllLinesParser parser = new AllLinesParser(); command.add(script); command.add(routerIp); @@ -386,7 +387,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _updateHostPasswdPath; } - public int getTimeout() { + public Duration getTimeout() { return _timeout; } @@ -777,7 +778,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } value = (String)params.get("scripts.timeout"); - _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000; + _timeout = Duration.standardSeconds(NumbersUtil.parseInt(value, 30 * 60)); value = (String)params.get("stop.script.timeout"); _stopTimeout = NumbersUtil.parseInt(value, 120) * 1000; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java index b840e8b472c..03d9cf94561 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java @@ -29,7 +29,7 @@ import com.cloud.resource.CommandWrapper; import com.cloud.resource.ResourceWrapper; import com.cloud.utils.script.Script; -@ResourceWrapper(handles = OvsCreateTunnelCommand.class) +@ResourceWrapper(handles = OvsCreateTunnelCommand.class) public final class LibvirtOvsCreateTunnelCommandWrapper extends CommandWrapper { private static final Logger s_logger = Logger.getLogger(LibvirtOvsCreateTunnelCommandWrapper.class); @@ -40,13 +40,10 @@ public final class LibvirtOvsCreateTunnelCommandWrapper extends CommandWrapper result; //TODO: Password should be masked, cannot output to log directly @@ -1280,7 +1282,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa try { VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); result = SshHelper.sshExecute(routerIP, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args, - 60000, 60000, timeout * 1000); + VRScripts.CONNECTION_TIMEOUT, VRScripts.CONNECTION_TIMEOUT, timeout); } catch (Exception e) { String msg = "Command failed due to " + VmwareHelper.getExceptionMessage(e); s_logger.error(msg); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 026d0c18cd2..2865e56fd30 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -29,6 +29,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.Charset; +import org.joda.time.Duration; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -97,6 +98,7 @@ 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.VirtualMachineTO; +import com.cloud.agent.resource.virtualnetwork.VRScripts; import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.exception.InternalErrorException; @@ -1660,18 +1662,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe @Override public ExecutionResult executeInVR(final String routerIP, final String script, final String args) { // Timeout is 120 seconds by default - return executeInVR(routerIP, script, args, 120); + return executeInVR(routerIP, script, args, VRScripts.VR_SCRIPT_EXEC_TIMEOUT); } @Override - public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final int timeout) { + public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final Duration timeout) { Pair result; String cmdline = "/opt/cloud/bin/router_proxy.sh " + script + " " + routerIP + " " + args; // semicolon need to be escape for bash cmdline = cmdline.replaceAll(";", "\\\\;"); try { s_logger.debug("Executing command in VR: " + cmdline); - result = SshHelper.sshExecute(_host.getIp(), 22, _username, null, _password.peek(), cmdline, 60000, 60000, timeout * 1000); + result = SshHelper.sshExecute(_host.getIp(), 22, _username, null, _password.peek(), cmdline, VRScripts.CONNECTION_TIMEOUT, VRScripts.CONNECTION_TIMEOUT, timeout); } catch (final Exception e) { return new ExecutionResult(false, e.getMessage()); } diff --git a/utils/src/main/java/com/cloud/utils/script/Script.java b/utils/src/main/java/com/cloud/utils/script/Script.java index b8cb4fe8ce4..76084751417 100644 --- a/utils/src/main/java/com/cloud/utils/script/Script.java +++ b/utils/src/main/java/com/cloud/utils/script/Script.java @@ -39,6 +39,7 @@ import java.util.concurrent.TimeUnit; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; +import org.joda.time.Duration; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.concurrency.NamedThreadFactory; @@ -64,10 +65,15 @@ public class Script implements Callable { Process _process; Thread _thread; - public int getExitValue() { + public int getExitValue() { return _process.exitValue(); } + public Script(String command, Duration timeout, Logger logger) { + this(command, timeout.getMillis(), logger); + } + + @Deprecated public Script(String command, long timeout, Logger logger) { _command = new ArrayList(); _command.add(command); @@ -80,6 +86,11 @@ public class Script implements Callable { _logger = logger != null ? logger : s_logger; } + public Script(boolean runWithSudo, String command, Duration timeout, Logger logger) { + this(runWithSudo, command, timeout.getMillis(), logger); + } + + @Deprecated public Script(boolean runWithSudo, String command, long timeout, Logger logger) { this(command, timeout, logger); if (runWithSudo) { @@ -95,6 +106,11 @@ public class Script implements Callable { this(command, 0, s_logger); } + public Script(String command, Duration timeout) { + this(command, timeout.getMillis(), s_logger); + } + + @Deprecated public Script(String command, long timeout) { this(command, timeout, s_logger); } diff --git a/utils/src/main/java/com/cloud/utils/ssh/SshHelper.java b/utils/src/main/java/com/cloud/utils/ssh/SshHelper.java index 1f6d30c0099..a86a4850b13 100644 --- a/utils/src/main/java/com/cloud/utils/ssh/SshHelper.java +++ b/utils/src/main/java/com/cloud/utils/ssh/SshHelper.java @@ -28,6 +28,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import org.joda.time.Duration; import com.trilead.ssh2.ChannelCondition; import com.trilead.ssh2.Connection; @@ -134,8 +135,12 @@ public class SshHelper { } } - public static Pair sshExecute(String host, int port, String user, File pemKeyFile, String password, String command, int connectTimeoutInMs, - int kexTimeoutInMs, + public static Pair sshExecute(String host, int port, String user, File pemKeyFile, String password, String command, Duration connectTimeout, + Duration kexTimeout, Duration waitTime) throws Exception { + return sshExecute(host, port, user, pemKeyFile, password, command, (int)connectTimeout.getMillis(), (int)kexTimeout.getMillis(), (int)waitTime.getMillis()); + } + + public static Pair sshExecute(String host, int port, String user, File pemKeyFile, String password, String command, int connectTimeoutInMs, int kexTimeoutInMs, int waitResultTimeoutInMs) throws Exception { com.trilead.ssh2.Connection conn = null;