From 9692e29bfc8c10daac6b3209b5083daf6cbcad49 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Tue, 3 Feb 2026 15:19:35 +0530 Subject: [PATCH 1/2] Support for custom SSH port for KVM hosts using the configuration 'kvm.host.discovery.ssh.port' - Use the custom SSH port for KVM host discovery to connect to the Host during Add Host command - and any other operations on host using SSH --- .../src/main/java/com/cloud/agent/AgentManager.java | 3 +++ .../main/java/com/cloud/agent/manager/AgentManagerImpl.java | 2 +- .../apache/cloudstack/backup/NetworkerBackupProvider.java | 5 +++-- .../hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java | 2 +- .../main/java/com/cloud/resource/ResourceManagerImpl.java | 2 +- utils/src/main/java/com/cloud/utils/ssh/SSHCmdHelper.java | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java b/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java index b29eb38395fa..3c6d7fb28919 100644 --- a/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java +++ b/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java @@ -54,6 +54,9 @@ public interface AgentManager { "This timeout overrides the wait global config. This holds a comma separated key value pairs containing timeout (in seconds) for specific commands. " + "For example: DhcpEntryCommand=600, SavePasswordCommand=300, VmDataCommand=300", false); + ConfigKey KVMHostDiscoverySshPort = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Integer.class, + "kvm.host.discovery.ssh.port", "22", "SSH port used for KVM host discovery and any other operations on host (using SSH)", true); + enum TapAgentsAction { Add, Del, Contains, } diff --git a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java index 2b5e81eb3f9b..bfdd2387bc42 100644 --- a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java @@ -1977,7 +1977,7 @@ public ConfigKey[] getConfigKeys() { return new ConfigKey[] { CheckTxnBeforeSending, Workers, Port, Wait, AlertWait, DirectAgentLoadSize, DirectAgentPoolSize, DirectAgentThreadCap, EnableKVMAutoEnableDisable, ReadyCommandWait, GranularWaitTimeForCommands, RemoteAgentSslHandshakeTimeout, RemoteAgentMaxConcurrentNewConnections, - RemoteAgentNewConnectionsMonitorInterval }; + RemoteAgentNewConnectionsMonitorInterval, KVMHostDiscoverySshPort }; } protected class SetHostParamsListener implements Listener { diff --git a/plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java b/plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java index 393e2911ac38..89dfc545c506 100644 --- a/plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java +++ b/plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.backup; +import com.cloud.agent.AgentManager; import com.cloud.dc.dao.ClusterDao; import com.cloud.host.HostVO; import com.cloud.host.Status; @@ -230,7 +231,7 @@ private String executeBackupCommand(HostVO host, String username, String passwor Pattern saveTimePattern = Pattern.compile(nstRegex); try { - Pair response = SshHelper.sshExecute(host.getPrivateIpAddress(), 22, + Pair response = SshHelper.sshExecute(host.getPrivateIpAddress(), AgentManager.KVMHostDiscoverySshPort.value(), username, null, password, command, 120000, 120000, 3600000); if (!response.first()) { LOG.error(String.format("Backup Script failed on HYPERVISOR %s due to: %s", host, response.second())); @@ -251,7 +252,7 @@ private String executeBackupCommand(HostVO host, String username, String passwor private boolean executeRestoreCommand(HostVO host, String username, String password, String command) { try { - Pair response = SshHelper.sshExecute(host.getPrivateIpAddress(), 22, + Pair response = SshHelper.sshExecute(host.getPrivateIpAddress(), AgentManager.KVMHostDiscoverySshPort.value(), username, null, password, command, 120000, 120000, 3600000); if (!response.first()) { diff --git a/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index 8f7bf21dff22..67abdb7af561 100644 --- a/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -272,7 +272,7 @@ private void setupAgentSecurity(final Connection sshConnection, final String age } } - sshConnection = new Connection(agentIp, 22); + sshConnection = new Connection(agentIp, AgentManager.KVMHostDiscoverySshPort.value()); sshConnection.connect(null, 60000, 60000); diff --git a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java index 12ceac213228..c46f341e7911 100755 --- a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java @@ -2949,7 +2949,7 @@ protected Ternary getHostCredentials(HostVO host) { */ protected void connectAndRestartAgentOnHost(HostVO host, String username, String password, String privateKey) { final com.trilead.ssh2.Connection connection = SSHCmdHelper.acquireAuthorizedConnection( - host.getPrivateIpAddress(), 22, username, password, privateKey); + host.getPrivateIpAddress(), AgentManager.KVMHostDiscoverySshPort.value(), username, password, privateKey); if (connection == null) { throw new CloudRuntimeException(String.format("SSH to agent is enabled, but failed to connect to %s via IP address [%s].", host, host.getPrivateIpAddress())); } diff --git a/utils/src/main/java/com/cloud/utils/ssh/SSHCmdHelper.java b/utils/src/main/java/com/cloud/utils/ssh/SSHCmdHelper.java index dd1c17aa3c02..944f63391a9a 100644 --- a/utils/src/main/java/com/cloud/utils/ssh/SSHCmdHelper.java +++ b/utils/src/main/java/com/cloud/utils/ssh/SSHCmdHelper.java @@ -77,7 +77,7 @@ public static com.trilead.ssh2.Connection acquireAuthorizedConnection(String ip, } public static com.trilead.ssh2.Connection acquireAuthorizedConnection(String ip, int port, String username, String password) { - return acquireAuthorizedConnection(ip, 22, username, password, null); + return acquireAuthorizedConnection(ip, port, username, password, null); } public static boolean acquireAuthorizedConnectionWithPublicKey(final com.trilead.ssh2.Connection sshConnection, final String username, final String privateKey) { From 2e49b0c8cb8a861a51df79b74d0d905198817354 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Wed, 4 Feb 2026 13:25:21 +0530 Subject: [PATCH 2/2] Update engine/components-api/src/main/java/com/cloud/agent/AgentManager.java --- .../src/main/java/com/cloud/agent/AgentManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java b/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java index 3c6d7fb28919..7690dc14d8a1 100644 --- a/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java +++ b/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java @@ -55,7 +55,7 @@ public interface AgentManager { "For example: DhcpEntryCommand=600, SavePasswordCommand=300, VmDataCommand=300", false); ConfigKey KVMHostDiscoverySshPort = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Integer.class, - "kvm.host.discovery.ssh.port", "22", "SSH port used for KVM host discovery and any other operations on host (using SSH)", true); + "kvm.host.discovery.ssh.port", "22", "SSH port used for KVM host discovery and any other operations on host (using SSH). Please note that this is applicable for all the KVM hosts added to this CloudStack deployment, so ensure all hosts are accessible on this port", true); enum TapAgentsAction { Add, Del, Contains,