Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<Integer> KVMHostDiscoverySshPort = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Integer.class,
Copy link
Member

@winterhazel winterhazel Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to have this as a parameter on host addition/edit to allow configuring it on a host-level?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can, but do we really want to allow to use a different ssh port for all hosts within a cluster? seems a bit overkill.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a problem allowing it. Maybe a single host needs to use a different port for SSH connection.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, a bit of an edge case, only applicable to smaller installations I’d guess (in my ignorance). You are not asking to remove a higher level setting are you? just to add a per host parameter..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the config is applicable for the kvm hosts on the entire cloudstack installation, mainly for large deployments where the custom port is used for all the hosts. it doesn't provide flexibility to set few hosts on one port, and few hosts on the other. it's always better to have all these hosts accessible on the same port. a new host parameter (that can be updated through add or update host call) can provide flexibility, but it's mostly NULL/empty (when not defined or default port is used) and is not applicable for VMware hosts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add only the host parameter , not the global parameter

Copy link
Contributor Author

@sureshanaparti sureshanaparti Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the host config is not allowed to set from the ui during host addition, so host discovery would fail (currently from cmk/api - we can pass particular detail for the config, or requires updating ui to take it as input and set the detail)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sureshanaparti
one option would be allowing host:port when adding a host
it is compatible with current format: host. no UI changes, no global settings

similar to the ceph monitors which supports mon1,mon2,mon3:6789 as the monitor
refer to #6792

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so reading back this threat; are we not merging this and going for a different solution, @winterhazel @weizhouapache ? cc @sureshanaparti

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no threat @DaanHoogland 😄

I think it would be better to work on a different solution

"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,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -230,7 +231,7 @@ private String executeBackupCommand(HostVO host, String username, String passwor
Pattern saveTimePattern = Pattern.compile(nstRegex);

try {
Pair<Boolean, String> response = SshHelper.sshExecute(host.getPrivateIpAddress(), 22,
Pair<Boolean, String> 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()));
Expand All @@ -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<Boolean, String> response = SshHelper.sshExecute(host.getPrivateIpAddress(), 22,
Pair<Boolean, String> response = SshHelper.sshExecute(host.getPrivateIpAddress(), AgentManager.KVMHostDiscoverySshPort.value(),
username, null, password, command, 120000, 120000, 3600000);

if (!response.first()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2949,7 +2949,7 @@ protected Ternary<String, String, String> 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()));
}
Expand Down
2 changes: 1 addition & 1 deletion utils/src/main/java/com/cloud/utils/ssh/SSHCmdHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading