From 98cce96588d67263e7fc76e405ea5607a4b2d3b6 Mon Sep 17 00:00:00 2001 From: Laert Llaveshi Date: Mon, 29 Jun 2026 09:26:01 +0200 Subject: [PATCH 1/3] #854: Fix kubectl and docker path finding issue --- .../devonfw/tools/ide/tool/docker/Docker.java | 50 +++++++++++++++++-- .../tools/ide/tool/kubectl/KubeCtl.java | 15 ++++++ 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java b/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java index 4533c2fe99..4d35af69eb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java @@ -1,5 +1,7 @@ package com.devonfw.tools.ide.tool.docker; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -8,6 +10,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.devonfw.tools.ide.cli.CliException; import com.devonfw.tools.ide.common.Tag; import com.devonfw.tools.ide.context.IdeContext; import com.devonfw.tools.ide.os.SystemArchitecture; @@ -15,6 +18,8 @@ import com.devonfw.tools.ide.tool.GlobalToolCommandlet; import com.devonfw.tools.ide.tool.NativePackageManager; import com.devonfw.tools.ide.tool.PackageManagerCommand; +import com.devonfw.tools.ide.tool.ToolInstallRequest; +import com.devonfw.tools.ide.tool.ToolInstallation; import com.devonfw.tools.ide.tool.repository.ToolRepository; import com.devonfw.tools.ide.version.VersionIdentifier; @@ -49,16 +54,17 @@ public String getBinaryName() { } private boolean isDockerInstalled() { - return isCommandAvailable("docker"); + return resolveRancherDesktopCommand("docker") != null; } private boolean isRancherDesktopInstalled() { - return isCommandAvailable("rdctl"); + return resolveRancherDesktopCommand("rdctl") != null; } private String detectContainerRuntime() { - if (isCommandAvailable(this.tool)) { - return this.tool; + String docker = resolveRancherDesktopCommand(this.tool); + if (docker != null) { + return docker; } else if (isCommandAvailable(PODMAN)) { return PODMAN; } else { @@ -66,6 +72,28 @@ private String detectContainerRuntime() { } } + /** + * Rancher Desktop links its CLI tools (docker, kubectl, rdctl) into the fixed {@code ~/.rd/bin} directory, which it creates on its first launch. + * Depending on the user's path management strategy this directory may not be on the PATH, so we look it up there explicitly as a fallback. + * + * @param command the name of the Rancher Desktop CLI to resolve. + * @return the {@code command} unchanged if available on PATH, otherwise its absolute path inside {@code ~/.rd/bin} or {@code null} if not found. + */ + private String resolveRancherDesktopCommand(String command) { + if (isCommandAvailable(command)) { + return command; + } + Path rancherDesktopBinary = getRancherDesktopBinDir().resolve(command); + if (Files.exists(rancherDesktopBinary)) { + return rancherDesktopBinary.toString(); + } + return null; + } + + private Path getRancherDesktopBinDir() { + return this.context.getUserHome().resolve(".rd").resolve("bin"); + } + @Override public boolean isExtract() { @@ -76,6 +104,17 @@ public boolean isExtract() { }; } + @Override + protected ToolInstallation doInstall(ToolInstallRequest request) { + + ToolInstallation installation = super.doInstall(request); + if (this.context.getSystemInfo().isLinux() && !Files.isDirectory(getRancherDesktopBinDir())) { + throw new CliException("Rancher Desktop has been installed but not launched yet. Please start Rancher Desktop once so that it sets up its " + + "command-line tools (docker, kubectl, ...) in ~/.rd/bin, then re-run your command.", 2); + } + return installation; + } + @Override protected List getInstallPackageManagerCommands() { @@ -139,7 +178,8 @@ private VersionIdentifier getDockerDesktopVersionLinux() { private VersionIdentifier getRancherDesktopClientVersion() { - String output = this.context.newProcess().runAndGetSingleOutput("rdctl", "version"); + String rdctl = resolveRancherDesktopCommand("rdctl"); + String output = this.context.newProcess().runAndGetSingleOutput(rdctl, "version"); return super.resolveVersionWithPattern(output, RDCTL_CLIENT_VERSION_PATTERN); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/kubectl/KubeCtl.java b/cli/src/main/java/com/devonfw/tools/ide/tool/kubectl/KubeCtl.java index 50b3d72fc2..c9afd17785 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/kubectl/KubeCtl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/kubectl/KubeCtl.java @@ -1,5 +1,7 @@ package com.devonfw.tools.ide.tool.kubectl; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; import java.util.Set; import java.util.regex.Pattern; @@ -27,6 +29,19 @@ public KubeCtl(IdeContext context) { super(context, "kubectl", Set.of(Tag.KUBERNETES), Docker.class); } + @Override + protected String getBinaryName() { + + if (isCommandAvailable(this.tool)) { + return this.tool; + } + Path rancherDesktopBinary = this.context.getUserHome().resolve(".rd").resolve("bin").resolve(this.tool); + if (Files.exists(rancherDesktopBinary)) { + return rancherDesktopBinary.toString(); + } + return this.tool; + } + @Override public VersionIdentifier getInstalledVersion() { From 36d85af8747c3715e5cc2f83ce2c20597c1b8779 Mon Sep 17 00:00:00 2001 From: Laert Llaveshi Date: Mon, 29 Jun 2026 10:14:36 +0200 Subject: [PATCH 2/3] #854: Fix rdctl regex bug --- cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java b/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java index 4d35af69eb..d30844d1c7 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java @@ -34,7 +34,7 @@ public class Docker extends GlobalToolCommandlet { private static final String PODMAN = "podman"; - private static final Pattern RDCTL_CLIENT_VERSION_PATTERN = Pattern.compile("client version:\\s*v([\\d.]+)", Pattern.CASE_INSENSITIVE); + private static final Pattern RDCTL_CLIENT_VERSION_PATTERN = Pattern.compile("client version:\\s*v?([\\d.]+)", Pattern.CASE_INSENSITIVE); private static final Pattern DOCKER_DESKTOP_LINUX_VERSION_PATTERN = Pattern.compile("^([0-9]+(?:\\.[0-9]+){1,2})"); From 3f8d714e3097aeb1b0cd50648e132d95eae6fe65 Mon Sep 17 00:00:00 2001 From: Laert Llaveshi Date: Mon, 29 Jun 2026 10:31:38 +0200 Subject: [PATCH 3/3] Resolve conflicts during rebase. --- CHANGELOG.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 8237e2c626..fe43cac407 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -20,6 +20,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/2114[#2114]: Fix false "Cygwin is not supported" warning in Git Bash * https://github.com/devonfw/IDEasy/issues/865[#865]: az not working on Mac * https://github.com/devonfw/IDEasy/issues/2026[#2026]: Create UvRepository and UvBasedCommandlet +* https://github.com/devonfw/IDEasy/issues/854[#854]: Fix Rancher Desktop path The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/46?closed=1[milestone 2026.07.001].