Add agent test button

This commit is contained in:
crschnick
2026-02-25 22:08:40 +00:00
parent ad306362e4
commit 4f1a21a8d7
3 changed files with 75 additions and 11 deletions
@@ -10,6 +10,7 @@ import io.xpipe.app.process.ShellDialect;
import io.xpipe.app.secret.SecretRetrievalStrategy;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.vnc.VncBaseStore;
import io.xpipe.core.FilePath;
import io.xpipe.core.SecretValue;
import javafx.beans.property.Property;
@@ -78,4 +79,6 @@ public abstract class ProcessControlProvider {
public abstract void cloneRepository(String url, Path target) throws Exception;
public abstract void pullRepository(Path target) throws Exception;
public abstract void checkSshAgent(ShellControl sc, FilePath agent) throws Exception;
}
@@ -1,15 +1,30 @@
package io.xpipe.app.prefs;
import atlantafx.base.theme.Styles;
import io.xpipe.app.comp.BaseRegionBuilder;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.ContextualFileReferenceChoiceComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.issue.ErrorEventFactory;
import io.xpipe.app.platform.LabelGraphic;
import io.xpipe.app.platform.OptionsBuilder;
import io.xpipe.app.process.LocalShell;
import io.xpipe.app.process.ShellScript;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.terminal.TerminalLaunch;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.OsType;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.layout.Region;
import org.kordamp.ikonli.javafx.FontIcon;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
public class SshCategory extends AppPrefsCategory {
@@ -30,6 +45,36 @@ public class SshCategory extends AppPrefsCategory {
if (OsType.ofLocal() == OsType.WINDOWS) {
options.addComp(prefs.getCustomOptions("x11WslInstance").buildComp());
}
AtomicReference<Region> button = new AtomicReference<>();
var agentTest = new ButtonComp(AppI18n.observable("test"), new FontIcon("mdi2p-play"), () -> {
ThreadHelper.runFailableAsync(() -> {
var agent = prefs.sshAgentSocket().getValue();
if (agent == null) {
agent = prefs.defaultSshAgentSocket().getValue();
}
if (agent == null) {
return;
}
try {
ProcessControlProvider.get().checkSshAgent(LocalShell.getShell(), agent);
} catch (Exception e) {
ErrorEventFactory.fromThrowable(e).expected().handle();
return;
}
Platform.runLater(() -> {
button.get().getStyleClass().add(Styles.SUCCESS);
});
});
})
.padding(new Insets(6, 11, 6, 5))
.apply(struc -> struc.setAlignment(Pos.CENTER_LEFT));
agentTest.apply(struc -> button.set(struc));
if (OsType.ofLocal() != OsType.WINDOWS) {
var choice = new ContextualFileReferenceChoiceComp(
new ReadOnlyObjectWrapper<>(DataStorage.get().local().ref()),
@@ -41,7 +86,7 @@ public class SshCategory extends AppPrefsCategory {
choice.setPrompt(prefs.defaultSshAgentSocket);
choice.maxWidth(600);
options.sub(
new OptionsBuilder().nameAndDescription("sshAgentSocket").addComp(choice, prefs.sshAgentSocket));
new OptionsBuilder().nameAndDescription("sshAgentSocket").addComp(choice, prefs.sshAgentSocket).addComp(agentTest));
}
return options.buildComp();
}
@@ -13,6 +13,7 @@ import io.xpipe.app.process.ShellControl;
import io.xpipe.core.KeyValue;
import io.xpipe.core.OsType;
import javafx.beans.binding.Bindings;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
@@ -41,10 +42,13 @@ public class CustomAgentStrategy implements SshIdentityStrategy {
var publicKey =
new SimpleStringProperty(p.getValue() != null ? p.getValue().getPublicKey() : null);
var socket = AppPrefs.get().sshAgentSocket();
var socketBinding = BindingsHelper.map(socket, s -> {
return s != null ? s.toString() : AppI18n.get("agentSocketNotConfigured");
});
var socketBinding = Bindings.createObjectBinding(() -> {
var agent = AppPrefs.get().sshAgentSocket().getValue();
if (agent == null) {
agent = AppPrefs.get().defaultSshAgentSocket().getValue();
}
return agent != null ? agent.toString() : AppI18n.get("agentSocketNotConfigured");
}, AppPrefs.get().defaultSshAgentSocket(), AppPrefs.get().sshAgentSocket());
var socketProp = new SimpleStringProperty();
socketProp.bind(socketBinding);
var socketDisplay = new HorizontalComp(List.of(
@@ -62,8 +66,13 @@ public class CustomAgentStrategy implements SshIdentityStrategy {
.addComp(socketDisplay)
.check(val -> Validator.create(
val,
AppI18n.observable("agentSocketNotConfigured"),
AppPrefs.get().sshAgentSocket(),
AppI18n.observable("agentSocketNotConfigured"), Bindings.createObjectBinding(() -> {
var agent = AppPrefs.get().sshAgentSocket().getValue();
if (agent == null) {
agent = AppPrefs.get().defaultSshAgentSocket().getValue();
}
return agent;
}, AppPrefs.get().sshAgentSocket(), AppPrefs.get().defaultSshAgentSocket()),
i -> {
return i != null;
}))
@@ -90,8 +99,12 @@ public class CustomAgentStrategy implements SshIdentityStrategy {
@Override
public void prepareParent(ShellControl parent) throws Exception {
if (parent.isLocal()) {
var agent = AppPrefs.get().sshAgentSocket().getValue();
if (agent == null) {
agent = AppPrefs.get().defaultSshAgentSocket().getValue();
}
SshIdentityStateManager.prepareLocalCustomAgent(
parent, AppPrefs.get().sshAgentSocket().getValue());
parent, agent);
}
}
@@ -104,9 +117,12 @@ public class CustomAgentStrategy implements SshIdentityStrategy {
}
if (AppPrefs.get() != null) {
var socket = AppPrefs.get().sshAgentSocket().getValue();
if (socket != null) {
return socket.resolveTildeHome(sc.view().userHome()).toString();
var agent = AppPrefs.get().sshAgentSocket().getValue();
if (agent == null) {
agent = AppPrefs.get().defaultSshAgentSocket().getValue();
}
if (agent != null) {
return agent.resolveTildeHome(sc.view().userHome()).toString();
}
}