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
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,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].

Expand Down
52 changes: 46 additions & 6 deletions cli/src/main/java/com/devonfw/tools/ide/tool/docker/Docker.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -8,13 +10,16 @@
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;
import com.devonfw.tools.ide.os.WindowsHelper;
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;

Expand All @@ -29,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})");

Expand All @@ -49,23 +54,46 @@ 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 {
return this.tool;
}
}

/**
* 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() {

Expand All @@ -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<PackageManagerCommand> getInstallPackageManagerCommands() {

Expand Down Expand Up @@ -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);
}

Expand Down
15 changes: 15 additions & 0 deletions cli/src/main/java/com/devonfw/tools/ide/tool/kubectl/KubeCtl.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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() {

Expand Down
Loading