From af919ca0b376496e07afcb9b104f8f4428cf0498 Mon Sep 17 00:00:00 2001 From: Ole Herman Schumacher Elgesem Date: Fri, 3 Apr 2026 23:31:19 +0200 Subject: [PATCH 1/2] Fixed handling of role and agent fields in data Signed-off-by: Ole Herman Schumacher Elgesem --- cf_remote/commands.py | 4 ++-- cf_remote/remote.py | 29 +++++++++++++++++++++++------ cf_remote/ssh.py | 3 ++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/cf_remote/commands.py b/cf_remote/commands.py index 4e1cef1..90c499d 100644 --- a/cf_remote/commands.py +++ b/cf_remote/commands.py @@ -1056,10 +1056,10 @@ def agent(hosts, bootstrap=None): for host in hosts: data = get_info(host) - if not data["agent_location"]: + if not data["agent"]: raise CFRExitError("CFEngine not installed on {}".format(host)) - command = "{}".format(data["agent_location"]) + command = "{}".format(data["agent"]) if bootstrap: command += "--bootstrap {}".format(bootstrap[0]) diff --git a/cf_remote/remote.py b/cf_remote/remote.py index eeebdee..5e8c024 100644 --- a/cf_remote/remote.py +++ b/cf_remote/remote.py @@ -216,16 +216,30 @@ def get_info(host, *, users=None, connection=None): data["ssh_user"] = user systeminfo = ssh_cmd(connection, "systeminfo") + assert systeminfo is None or (type(systeminfo) is str and len(systeminfo) > 0) + # Note: ssh_cmd is supposed to return None on failure however, it seems + # like there are some cases where it returns output on failure + # because the exit code was 0 + # TODO: systeminfo has a lot of output normally, looking for + # "command not found" in this output is not very robust. if systeminfo and "command not found" not in systeminfo: data["os"] = "windows" data["systeminfo"] = parse_systeminfo(systeminfo) data["package_tags"] = ["x86_64", "msi"] data["arch"] = "x86_64" agent = r"& 'C:\Program Files\Cfengine\bin\cf-agent.exe'" - data["agent"] = agent version_cmd = powershell("{} -V".format(agent)) - data["agent_version"] = parse_version(ssh_cmd(connection, version_cmd)) + version_output = ssh_cmd(connection, version_cmd) + if version_output: + data["agent"] = agent + else: + data["agent"] = None + data["agent_version"] = parse_version(version_output) data["role"] = "client" + if data["agent_version"]: + data["role"] = "client" + else: + data["role"] = None else: data["os"] = "unix" @@ -270,12 +284,15 @@ def get_info(host, *, users=None, connection=None): data["package_tags"] = get_package_tags(os_release_data, redhat_release_data) data["cfengine_id"] = discovery.get("NTD_CFENGINE_ID") - data["agent_location"] = discovery.get("NTD_CFAGENT_PATH") + data["agent"] = discovery.get("NTD_CFAGENT_PATH") data["policy_server"] = discovery.get("NTD_POLICY_SERVER") - agent = r"/var/cfengine/bin/cf-agent" - data["agent"] = agent data["agent_version"] = parse_version(discovery.get("NTD_CFAGENT_VERSION")) - data["role"] = "hub" if discovery.get("NTD_CFHUB") else "client" + if discovery.get("NTD_CFHUB"): + data["role"] = "hub" + elif discovery.get("NTD_CFAGENT_PATH"): + data["role"] = "client" + else: + data["role"] = None data["bin"] = {} for bin in [ diff --git a/cf_remote/ssh.py b/cf_remote/ssh.py index 3d7b6ea..a4a41cb 100644 --- a/cf_remote/ssh.py +++ b/cf_remote/ssh.py @@ -4,6 +4,7 @@ import shutil import signal import subprocess +from typing import Union from urllib.parse import urlparse from cf_remote import aramid @@ -243,7 +244,7 @@ def scp(file, remote, connection=None, rename=None, hide=False): return 0 -def ssh_cmd(connection, cmd, errors=False, needs_pty=True): +def ssh_cmd(connection, cmd, errors=False, needs_pty=True) -> Union[str, None]: assert connection if needs_pty: From 08b100831958070afad39cad1bda2e2f0e05b31c Mon Sep 17 00:00:00 2001 From: Ole Herman Schumacher Elgesem Date: Fri, 3 Apr 2026 23:44:01 +0200 Subject: [PATCH 2/2] Tightened command not found check Signed-off-by: Ole Herman Schumacher Elgesem --- cf_remote/remote.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cf_remote/remote.py b/cf_remote/remote.py index 5e8c024..b8aee65 100644 --- a/cf_remote/remote.py +++ b/cf_remote/remote.py @@ -220,9 +220,10 @@ def get_info(host, *, users=None, connection=None): # Note: ssh_cmd is supposed to return None on failure however, it seems # like there are some cases where it returns output on failure # because the exit code was 0 - # TODO: systeminfo has a lot of output normally, looking for - # "command not found" in this output is not very robust. - if systeminfo and "command not found" not in systeminfo: + # TODO / Workaround: + if systeminfo == "bash: systeminfo: command not found": + systeminfo = None + if systeminfo: data["os"] = "windows" data["systeminfo"] = parse_systeminfo(systeminfo) data["package_tags"] = ["x86_64", "msi"]