mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 15:10:23 +00:00
More terminal launcher rework
This commit is contained in:
parent
20206b6263
commit
da42eb578f
45 changed files with 443 additions and 20 deletions
|
@ -65,8 +65,8 @@ dependencies {
|
|||
api group: 'org.kordamp.ikonli', name: 'ikonli-javafx', version: "12.2.0"
|
||||
api group: 'org.kordamp.ikonli', name: 'ikonli-material-pack', version: "12.2.0"
|
||||
api group: 'org.kordamp.ikonli', name: 'ikonli-feather-pack', version: "12.2.0"
|
||||
api group: 'org.slf4j', name: 'slf4j-api', version: '2.0.15'
|
||||
api group: 'org.slf4j', name: 'slf4j-jdk-platform-logging', version: '2.0.15'
|
||||
api group: 'org.slf4j', name: 'slf4j-api', version: '2.0.16'
|
||||
api group: 'org.slf4j', name: 'slf4j-jdk-platform-logging', version: '2.0.16'
|
||||
api 'io.xpipe:modulefs:0.1.5'
|
||||
api 'net.synedra:validatorfx:0.4.2'
|
||||
api files("$rootDir/gradle/gradle_scripts/atlantafx-base-2.0.2.jar")
|
||||
|
|
|
@ -25,7 +25,7 @@ public class SshLaunchExchangeImpl extends SshLaunchExchange {
|
|||
}
|
||||
TerminalLauncherManager.submitAsync(UUID.randomUUID(), ((ShellStore) DataStorage.get().local().getStore()).control(),
|
||||
TerminalInitScriptConfig.ofName("abc"),null);
|
||||
var r = TerminalLauncherManager.waitForFirstLaunch();
|
||||
var r = TerminalLauncherManager.waitForNextLaunch();
|
||||
var c = ProcessControlProvider.get().getEffectiveLocalDialect().getOpenScriptCommand(r.toString()).buildBaseParts(null);
|
||||
return Response.builder().command(c).build();
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import io.xpipe.app.util.*;
|
|||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
@ -16,6 +16,14 @@ import java.util.function.Supplier;
|
|||
|
||||
public interface ExternalRdpClientType extends PrefsChoiceValue {
|
||||
|
||||
public static ExternalRdpClientType getApplicationLauncher() {
|
||||
if (OsType.getLocal() == OsType.WINDOWS) {
|
||||
return MSTSC;
|
||||
} else {
|
||||
return AppPrefs.get().rdpClientType().getValue();
|
||||
}
|
||||
}
|
||||
|
||||
ExternalRdpClientType MSTSC = new PathCheckType("app.mstsc", "mstsc.exe", false) {
|
||||
|
||||
@Override
|
||||
|
@ -62,6 +70,37 @@ public interface ExternalRdpClientType extends PrefsChoiceValue {
|
|||
return cmd.readStdoutOrThrow();
|
||||
}
|
||||
};
|
||||
|
||||
ExternalRdpClientType DEVOLUTIONS = new WindowsType("app.devolutions", "RemoteDesktopManager") {
|
||||
|
||||
@Override
|
||||
protected Optional<Path> determineInstallation() {
|
||||
try {
|
||||
var r = WindowsRegistry.local().readValue(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\rdm\\DefaultIcon");
|
||||
return r.map(Path::of);
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).omit().handle();
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(Path file, LaunchConfiguration configuration) throws Exception {
|
||||
var config = writeConfig(configuration.getConfig());
|
||||
LocalShell.getShell().executeSimpleCommand(CommandBuilder.of().addFile(file.toString()).addFile(config.toString()).discardOutput());
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
// Startup is slow
|
||||
ThreadHelper.sleep(10000);
|
||||
Files.delete(config);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
ExternalRdpClientType REMMINA = new PathCheckType("app.remmina", "remmina", true) {
|
||||
|
||||
@Override
|
||||
|
@ -96,7 +135,7 @@ public interface ExternalRdpClientType extends PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
ExternalRdpClientType CUSTOM = new CustomType();
|
||||
List<ExternalRdpClientType> WINDOWS_CLIENTS = List.of(MSTSC);
|
||||
List<ExternalRdpClientType> WINDOWS_CLIENTS = List.of(MSTSC, DEVOLUTIONS);
|
||||
List<ExternalRdpClientType> LINUX_CLIENTS = List.of(REMMINA);
|
||||
List<ExternalRdpClientType> MACOS_CLIENTS = List.of(MICROSOFT_REMOTE_DESKTOP_MACOS_APP);
|
||||
|
||||
|
@ -145,6 +184,29 @@ public interface ExternalRdpClientType extends PrefsChoiceValue {
|
|||
SecretValue password;
|
||||
}
|
||||
|
||||
abstract class WindowsType extends ExternalApplicationType.WindowsType implements ExternalRdpClientType {
|
||||
|
||||
public WindowsType(String id, String executable) {
|
||||
super(id, executable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||
var location = determineFromPath();
|
||||
if (location.isEmpty()) {
|
||||
location = determineInstallation();
|
||||
if (location.isEmpty()) {
|
||||
throw new IOException("Unable to find installation of "
|
||||
+ toTranslatedString().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
execute(location.get(), configuration);
|
||||
}
|
||||
|
||||
protected abstract void execute(Path file, LaunchConfiguration configuration) throws Exception;
|
||||
}
|
||||
|
||||
abstract class PathCheckType extends ExternalApplicationType.PathApplication implements ExternalRdpClientType {
|
||||
|
||||
public PathCheckType(String id, String executable, boolean explicityAsync) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.storage;
|
|||
|
||||
import io.xpipe.app.comp.store.StoreSortMode;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.FixedHierarchyStore;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
@ -120,9 +121,11 @@ public abstract class DataStorage {
|
|||
}
|
||||
|
||||
public void forceRewrite() {
|
||||
TrackEvent.info("Starting forced storage rewrite");
|
||||
getStoreEntries().forEach(dataStoreEntry -> {
|
||||
dataStoreEntry.reassignStore();
|
||||
});
|
||||
TrackEvent.info("Finished forced storage rewrite");
|
||||
}
|
||||
|
||||
private void dispose() {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package io.xpipe.app.terminal;
|
||||
|
||||
import io.xpipe.app.comp.base.MarkdownComp;
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.ExternalApplicationType;
|
||||
|
@ -8,18 +12,181 @@ import io.xpipe.app.util.*;
|
|||
import io.xpipe.core.process.*;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.util.FailableFunction;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonBar;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import lombok.Getter;
|
||||
import lombok.Value;
|
||||
import lombok.With;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||
|
||||
// ExternalTerminalType PUTTY = new WindowsType("app.putty","putty") {
|
||||
//
|
||||
// @Override
|
||||
// protected Optional<Path> determineInstallation() {
|
||||
// try {
|
||||
// var r = WindowsRegistry.local().readValue(WindowsRegistry.HKEY_LOCAL_MACHINE,
|
||||
// "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Xshell.exe");
|
||||
// return r.map(Path::of);
|
||||
// } catch (Exception e) {
|
||||
// ErrorEvent.fromThrowable(e).omit().handle();
|
||||
// return Optional.empty();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean supportsTabs() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isRecommended() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean supportsColoredTitle() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void execute(Path file, LaunchConfiguration configuration) throws Exception {
|
||||
// try (var sc = LocalShell.getShell()) {
|
||||
// SshLocalBridge.init();
|
||||
// var b = SshLocalBridge.get();
|
||||
// var command = CommandBuilder.of().addFile(file.toString()).add("-ssh", "localhost", "-l").addQuoted(b.getUser())
|
||||
// .add("-i").addFile(b.getIdentityKey().toString()).add("-P", "" + b.getPort()).add("-hostkey").addFile(b.getPubHostKey().toString());
|
||||
// sc.executeSimpleCommand(command);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
ExternalTerminalType XSHELL = new WindowsType("app.xShell","Xshell") {
|
||||
|
||||
@Override
|
||||
protected Optional<Path> determineInstallation() {
|
||||
try {
|
||||
var r = WindowsRegistry.local().readValue(WindowsRegistry.HKEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Xshell.exe");
|
||||
return r.map(Path::of);
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).omit().handle();
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTabs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecommended() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsColoredTitle() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(Path file, LaunchConfiguration configuration) throws Exception {
|
||||
SshLocalBridge.init();
|
||||
if (!showInfo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (var sc = LocalShell.getShell()) {
|
||||
var b = SshLocalBridge.get();
|
||||
var command = CommandBuilder.of().addFile(file.toString()).add("-url").addQuoted("ssh://" + b.getUser() + "@localhost:" + b.getPort())
|
||||
.add("-i", "xpipe_bridge");
|
||||
sc.executeSimpleCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean showInfo() {
|
||||
boolean set = AppCache.get("xshellSetup", Boolean.class, () -> false);
|
||||
if (set) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var b = SshLocalBridge.get();
|
||||
var r = AppWindowHelper.showBlockingAlert(
|
||||
alert -> {
|
||||
alert.setTitle(AppI18n.get("xshellSetup"));
|
||||
alert.setAlertType(Alert.AlertType.NONE);
|
||||
|
||||
var activated = AppI18n.get().getMarkdownDocumentation("app:xshellSetup");
|
||||
var markdown = new MarkdownComp(activated, s -> s.formatted(b.getIdentityKey(), "xpipe_bridge"))
|
||||
.prefWidth(450)
|
||||
.prefHeight(400)
|
||||
.createRegion();
|
||||
alert.getDialogPane().setContent(markdown);
|
||||
|
||||
alert.getButtonTypes().add(new ButtonType(AppI18n.get("ok"), ButtonBar.ButtonData.OK_DONE));
|
||||
});
|
||||
r.filter(buttonType -> buttonType.getButtonData().isDefaultButton());
|
||||
r.ifPresent(buttonType -> {
|
||||
AppCache.update("xshellSetup", true);
|
||||
});
|
||||
return r.isPresent();
|
||||
}
|
||||
};
|
||||
|
||||
ExternalTerminalType SECURECRT = new WindowsType("app.secureCrt","SecureCRT") {
|
||||
|
||||
@Override
|
||||
protected Optional<Path> determineInstallation() {
|
||||
try (var sc = LocalShell.getShell().start()) {
|
||||
var env = sc.executeSimpleStringCommand(
|
||||
sc.getShellDialect().getPrintEnvironmentVariableCommand("ProgramFiles"));
|
||||
var file = Path.of(env, "VanDyke Software\\SecureCRT\\SecureCRT.exe");
|
||||
if (!Files.exists(file)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(file);
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).omit().handle();
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTabs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecommended() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsColoredTitle() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(Path file, LaunchConfiguration configuration) throws Exception {
|
||||
try (var sc = LocalShell.getShell()) {
|
||||
SshLocalBridge.init();
|
||||
var b = SshLocalBridge.get();
|
||||
var command = CommandBuilder.of().addFile(file.toString()).add("/T").add("/SSH2", "/ACCEPTHOSTKEYS", "/I").addFile(
|
||||
b.getIdentityKey().toString()).add("/P", "" + b.getPort()).add("/L").addQuoted(b.getUser()).add("localhost");
|
||||
sc.executeSimpleCommand(command);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ExternalTerminalType MOBAXTERM = new WindowsType("app.mobaXterm","MobaXterm") {
|
||||
|
||||
@Override
|
||||
|
@ -108,12 +275,44 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
@Override
|
||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||
SshLocalBridge.init();
|
||||
if (!showInfo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var name = "xpipe_bridge";
|
||||
var host = "localhost";
|
||||
var port = 21722;
|
||||
var user = System.getProperty("user.name");
|
||||
var port = SshLocalBridge.get().getPort();
|
||||
var user = SshLocalBridge.get().getUser();
|
||||
Hyperlinks.open("termius://app/host-sharing#label=" + name + "&ip=" + host + "&port=" + port + "&username="
|
||||
+ user + "&os=windows");
|
||||
+ user + "&os=undefined");
|
||||
}
|
||||
|
||||
private boolean showInfo() {
|
||||
boolean set = AppCache.get("termiusSetup", Boolean.class, () -> false);
|
||||
if (set) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var b = SshLocalBridge.get();
|
||||
var r = AppWindowHelper.showBlockingAlert(
|
||||
alert -> {
|
||||
alert.setTitle(AppI18n.get("termiusSetup"));
|
||||
alert.setAlertType(Alert.AlertType.NONE);
|
||||
|
||||
var activated = AppI18n.get().getMarkdownDocumentation("app:termiusSetup");
|
||||
var markdown = new MarkdownComp(activated, s -> s.formatted(b.getIdentityKey(), "xpipe_bridge"))
|
||||
.prefWidth(450)
|
||||
.prefHeight(400)
|
||||
.createRegion();
|
||||
alert.getDialogPane().setContent(markdown);
|
||||
|
||||
alert.getButtonTypes().add(new ButtonType(AppI18n.get("ok"), ButtonBar.ButtonData.OK_DONE));
|
||||
});
|
||||
r.filter(buttonType -> buttonType.getButtonData().isDefaultButton());
|
||||
r.ifPresent(buttonType -> {
|
||||
AppCache.update("termiusSetup", true);
|
||||
});
|
||||
return r.isPresent();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -747,8 +946,10 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
TabbyTerminalType.TABBY_WINDOWS,
|
||||
AlacrittyTerminalType.ALACRITTY_WINDOWS,
|
||||
WezTerminalType.WEZTERM_WINDOWS,
|
||||
TERMIUS,
|
||||
MOBAXTERM,
|
||||
SECURECRT,
|
||||
TERMIUS,
|
||||
XSHELL,
|
||||
CMD,
|
||||
PWSH,
|
||||
POWERSHELL);
|
||||
|
|
|
@ -20,6 +20,10 @@ public class SshLocalBridge {
|
|||
|
||||
private static SshLocalBridge INSTANCE;
|
||||
|
||||
public static SshLocalBridge get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private final Path directory;
|
||||
private final int port;
|
||||
private final String user;
|
||||
|
@ -33,19 +37,19 @@ public class SshLocalBridge {
|
|||
}
|
||||
|
||||
public Path getPubHostKey() {
|
||||
return directory.resolve("host_key.pub");
|
||||
return directory.resolve("xpipe_bridge_host_key.pub");
|
||||
}
|
||||
|
||||
public Path getHostKey() {
|
||||
return directory.resolve("host_key");
|
||||
return directory.resolve("xpipe_bridge_host_key");
|
||||
}
|
||||
|
||||
public Path getPubIdentityKey() {
|
||||
return directory.resolve("identity.pub");
|
||||
return directory.resolve("xpipe_bridge.pub");
|
||||
}
|
||||
|
||||
public Path getIdentityKey() {
|
||||
return directory.resolve("identity");
|
||||
return directory.resolve("xpipe_bridge");
|
||||
}
|
||||
|
||||
public Path getConfig() {
|
||||
|
@ -66,12 +70,15 @@ public class SshLocalBridge {
|
|||
|
||||
var hostKey = INSTANCE.getHostKey();
|
||||
if (!sc.getShellDialect().createFileExistsCommand(sc, hostKey.toString()).executeAndCheck()) {
|
||||
sc.executeSimpleCommand("ssh-keygen -q -N \"\" -t ed25519 -f \"" + hostKey + "\"");
|
||||
sc.command(CommandBuilder.of().add("ssh-keygen", "-q", "-N")
|
||||
.addQuoted("").add("-C").addQuoted("XPipe SSH bridge host key")
|
||||
.add("-t", "ed25519", "-f").addFile(hostKey.toString())).execute();
|
||||
}
|
||||
|
||||
var idKey = INSTANCE.getIdentityKey();
|
||||
if (!sc.getShellDialect().createFileExistsCommand(sc, idKey.toString()).executeAndCheck()) {
|
||||
sc.executeSimpleCommand("ssh-keygen -q -N \"\" -t ed25519 -f \"" + idKey + "\"");
|
||||
sc.command(CommandBuilder.of().add("ssh-keygen", "-q", "-N")
|
||||
.addQuoted("").add("-C").addQuoted("XPipe SSH bridge identity").add("-t", "ed25519", "-f").addFile(idKey.toString())).execute();
|
||||
}
|
||||
|
||||
var config = INSTANCE.getConfig();
|
||||
|
@ -92,7 +99,7 @@ public class SshLocalBridge {
|
|||
.formatted(command, pidFile.toString(), "" + port, INSTANCE.getHostKey().toString(), INSTANCE.getPubIdentityKey());;
|
||||
Files.writeString(config, content);
|
||||
|
||||
INSTANCE.updateConfig();
|
||||
// INSTANCE.updateConfig();
|
||||
|
||||
var exec = getSshd(sc);
|
||||
var launchCommand = CommandBuilder.of().addFile(exec).add("-f").addFile(INSTANCE.getConfig().toString()).add("-p", "" + port);
|
||||
|
|
|
@ -72,12 +72,13 @@ public class TerminalLauncherManager {
|
|||
return latch;
|
||||
}
|
||||
|
||||
public static Path waitForFirstLaunch() throws BeaconClientException, BeaconServerException {
|
||||
public static Path waitForNextLaunch() throws BeaconClientException, BeaconServerException {
|
||||
if (entries.isEmpty()) {
|
||||
throw new BeaconClientException("Unknown launch request");
|
||||
}
|
||||
|
||||
var first = entries.firstEntry();
|
||||
entries.remove(first.getKey());
|
||||
return waitForCompletion(first.getKey());
|
||||
}
|
||||
|
||||
|
@ -94,8 +95,8 @@ public class TerminalLauncherManager {
|
|||
}
|
||||
|
||||
var r = e.getResult();
|
||||
entries.remove(request);
|
||||
if (r instanceof ResultFailure failure) {
|
||||
entries.remove(request);
|
||||
var t = failure.getThrowable();
|
||||
throw new BeaconServerException(t);
|
||||
}
|
||||
|
|
2
dist/licenses/slf4j.properties
vendored
2
dist/licenses/slf4j.properties
vendored
|
@ -1,4 +1,4 @@
|
|||
name=SLF4J
|
||||
version=2.0.15
|
||||
version=2.0.16
|
||||
license=MIT License
|
||||
link=https://www.slf4j.org/
|
|
@ -61,3 +61,8 @@ dashlane=Dashlane
|
|||
lastpass=LastPass
|
||||
macosKeychain=macOS keychain
|
||||
windowsTerminalCanary=Windows Terminal Canary
|
||||
secureCrt=SecureCRT
|
||||
xShell=Xshell
|
||||
mobaXterm=MobaXterm
|
||||
termius=Termius
|
||||
devolutions=Devolutions
|
||||
|
|
|
@ -503,3 +503,5 @@ workspaceCreationAlertTitle=Oprettelse af arbejdsområde
|
|||
developerForceSshTty=Fremtving SSH TTY
|
||||
developerForceSshTtyDescription=Få alle SSH-forbindelser til at tildele en pty for at teste understøttelsen af en manglende stderr og en pty.
|
||||
ttyWarning=Forbindelsen har tvangstildelt en pty/tty og giver ikke en separat stderr-strøm.\n\nDet kan føre til et par problemer.\n\nHvis du kan, så prøv at få forbindelseskommandoen til ikke at tildele en pty.
|
||||
xshellSetup=Xshell-opsætning
|
||||
termiusSetup=Termius-opsætning
|
||||
|
|
|
@ -497,3 +497,5 @@ workspaceCreationAlertTitle=Arbeitsbereich erstellen
|
|||
developerForceSshTty=SSH TTY erzwingen
|
||||
developerForceSshTtyDescription=Lass alle SSH-Verbindungen ein pty zuweisen, um die Unterstützung für einen fehlenden stderr und ein pty zu testen.
|
||||
ttyWarning=Die Verbindung hat zwangsweise ein pty/tty zugewiesen und stellt keinen separaten stderr-Stream zur Verfügung.\n\nDas kann zu einigen Problemen führen.\n\nWenn du kannst, solltest du dafür sorgen, dass der Verbindungsbefehl kein pty zuweist.
|
||||
xshellSetup=Xshell-Einrichtung
|
||||
termiusSetup=Termius Einrichtung
|
||||
|
|
|
@ -501,3 +501,5 @@ workspaceCreationAlertTitle=Workspace creation
|
|||
developerForceSshTty=Force SSH TTY
|
||||
developerForceSshTtyDescription=Make all SSH connections allocate a pty to test the support for a missing stderr and a pty.
|
||||
ttyWarning=The connection has forcefully allocated a pty/tty and does not provide a separate stderr stream.\n\nThis might lead to a few problems.\n\nIf you can, look into making the connection command not allocate a pty.
|
||||
xshellSetup=Xshell setup
|
||||
termiusSetup=Termius setup
|
||||
|
|
|
@ -484,3 +484,5 @@ workspaceCreationAlertTitle=Creación de espacios de trabajo
|
|||
developerForceSshTty=Forzar SSH TTY
|
||||
developerForceSshTtyDescription=Haz que todas las conexiones SSH asignen una pty para probar la compatibilidad con una stderr y una pty ausentes.
|
||||
ttyWarning=La conexión ha asignado forzosamente un pty/tty y no proporciona un flujo stderr separado.\n\nEsto puede provocar algunos problemas.\n\nSi puedes, intenta que el comando de conexión no asigne una pty.
|
||||
xshellSetup=Configuración de Xshell
|
||||
termiusSetup=Configuración de Termius
|
||||
|
|
|
@ -484,3 +484,5 @@ workspaceCreationAlertTitle=Création d'un espace de travail
|
|||
developerForceSshTty=Force SSH TTY
|
||||
developerForceSshTtyDescription=Fais en sorte que toutes les connexions SSH allouent un pty pour tester la prise en charge d'un stderr et d'un pty manquants.
|
||||
ttyWarning=La connexion a alloué de force un pty/tty et ne fournit pas de flux stderr séparé.\n\nCela peut entraîner quelques problèmes.\n\nSi tu le peux, essaie de faire en sorte que la commande de connexion n'alloue pas de pty.
|
||||
xshellSetup=Configuration de Xshell
|
||||
termiusSetup=Installation de Termius
|
||||
|
|
|
@ -484,3 +484,5 @@ workspaceCreationAlertTitle=Creazione di uno spazio di lavoro
|
|||
developerForceSshTty=Forza SSH TTY
|
||||
developerForceSshTtyDescription=Fai in modo che tutte le connessioni SSH allocino una pty per testare il supporto di una stderr e di una pty mancanti.
|
||||
ttyWarning=La connessione ha allocato forzatamente una pty/tty e non fornisce un flusso stderr separato.\n\nQuesto potrebbe causare alcuni problemi.\n\nSe puoi, cerca di fare in modo che il comando di connessione non allarghi una pty.
|
||||
xshellSetup=Configurazione di Xshell
|
||||
termiusSetup=Configurazione di Termius
|
||||
|
|
|
@ -484,3 +484,5 @@ workspaceCreationAlertTitle=ワークスペースの作成
|
|||
developerForceSshTty=強制SSH TTY
|
||||
developerForceSshTtyDescription=すべてのSSHコネクションにptyを割り当て、stderrとptyがない場合のサポートをテストする。
|
||||
ttyWarning=接続が強制的にpty/ttyを割り当て、個別のstderrストリームを提供しない。\n\nこれはいくつかの問題を引き起こす可能性がある。\n\n可能であれば、接続コマンドで pty を割り当てないようにすることを検討してほしい。
|
||||
xshellSetup=Xshellのセットアップ
|
||||
termiusSetup=テルミウスのセットアップ
|
||||
|
|
|
@ -484,3 +484,5 @@ workspaceCreationAlertTitle=Werkruimte maken
|
|||
developerForceSshTty=SSH TTY afdwingen
|
||||
developerForceSshTtyDescription=Laat alle SSH-verbindingen een pty toewijzen om de ondersteuning voor een ontbrekende stderr en een pty te testen.
|
||||
ttyWarning=De verbinding heeft geforceerd een pty/tty toegewezen en biedt geen aparte stderr stream.\n\nDit kan tot een paar problemen leiden.\n\nAls je kunt, kijk dan of je het connection commando geen pty kunt laten toewijzen.
|
||||
xshellSetup=Xshell installatie
|
||||
termiusSetup=Termius installatie
|
||||
|
|
|
@ -484,3 +484,5 @@ workspaceCreationAlertTitle=Criação de espaço de trabalho
|
|||
developerForceSshTty=Força o SSH TTY
|
||||
developerForceSshTtyDescription=Faz com que todas as ligações SSH atribuam um pty para testar o suporte para um stderr e um pty em falta.
|
||||
ttyWarning=A ligação atribuiu à força um pty/tty e não fornece um fluxo stderr separado.\n\nIsto pode levar a alguns problemas.\n\nSe puderes, tenta fazer com que o comando de ligação não atribua um pty.
|
||||
xshellSetup=Configuração do Xshell
|
||||
termiusSetup=Configuração do Termius
|
||||
|
|
|
@ -484,3 +484,5 @@ workspaceCreationAlertTitle=Создание рабочего пространс
|
|||
developerForceSshTty=Принудительный SSH TTY
|
||||
developerForceSshTtyDescription=Заставь все SSH-соединения выделять pty, чтобы проверить поддержку отсутствующего stderr и pty.
|
||||
ttyWarning=Соединение принудительно выделило pty/tty и не предоставляет отдельный поток stderr.\n\nЭто может привести к нескольким проблемам.\n\nЕсли можешь, попробуй сделать так, чтобы команда подключения не выделяла pty.
|
||||
xshellSetup=Настройка Xshell
|
||||
termiusSetup=Настройка Термиуса
|
||||
|
|
|
@ -485,3 +485,5 @@ workspaceCreationAlertTitle=Çalışma alanı oluşturma
|
|||
developerForceSshTty=SSH TTY'yi Zorla
|
||||
developerForceSshTtyDescription=Eksik bir stderr ve bir pty desteğini test etmek için tüm SSH bağlantılarının bir pty ayırmasını sağlayın.
|
||||
ttyWarning=Bağlantı zorla bir pty/tty ayırmış ve ayrı bir stderr akışı sağlamıyor.\n\nBu durum birkaç soruna yol açabilir.\n\nEğer yapabiliyorsanız, bağlantı komutunun bir pty tahsis etmemesini sağlayın.
|
||||
xshellSetup=Xshell kurulumu
|
||||
termiusSetup=Termius kurulumu
|
||||
|
|
|
@ -484,3 +484,5 @@ workspaceCreationAlertTitle=创建工作区
|
|||
developerForceSshTty=强制 SSH TTY
|
||||
developerForceSshTtyDescription=让所有 SSH 连接都分配一个 pty,以测试对缺失的 stderr 和 pty 的支持。
|
||||
ttyWarning=连接强行分配了 pty/tty,且未提供单独的 stderr 流。\n\n这可能会导致一些问题。\n\n如果可以,请考虑让连接命令不分配 pty。
|
||||
xshellSetup=Xshell 设置
|
||||
termiusSetup=Termius 设置
|
||||
|
|
5
lang/app/texts/termiusSetup_da.md
Normal file
5
lang/app/texts/termiusSetup_da.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Termius setup
|
||||
|
||||
For at bruge Termius som din terminal kan du forbinde den til XPipe SSH-broen. Det kan ske automatisk, når den lokale ssh-nøgle til broen er blevet tilføjet til Termius.
|
||||
|
||||
Det eneste, du skal gøre manuelt, er at tilføje den private nøglefil `%s` til Termius først.
|
5
lang/app/texts/termiusSetup_de.md
Normal file
5
lang/app/texts/termiusSetup_de.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Termius setup
|
||||
|
||||
Um Termius als Terminal zu verwenden, kannst du ihn mit der XPipe SSH-Bridge verbinden. Das kann automatisch funktionieren, sobald der lokale Bridge-Ssh-Schlüssel zu Termius hinzugefügt wurde.
|
||||
|
||||
Das Einzige, was du manuell tun musst, ist, die private Schlüsseldatei `%s` zuerst zu Termius hinzuzufügen.
|
5
lang/app/texts/termiusSetup_en.md
Normal file
5
lang/app/texts/termiusSetup_en.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Termius setup
|
||||
|
||||
To use Termius as your terminal, you can connect it to the XPipe SSH bridge. This can work automatically once the local bridge ssh key has been added to Termius.
|
||||
|
||||
The only thing you have to do manually is to add the private key file `%s` to Termius first.
|
5
lang/app/texts/termiusSetup_es.md
Normal file
5
lang/app/texts/termiusSetup_es.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Configuración de Termius
|
||||
|
||||
Para utilizar Termius como terminal, puedes conectarlo al puente SSH de XPipe. Esto puede funcionar automáticamente una vez que se haya añadido a Termius la clave ssh del puente local.
|
||||
|
||||
Lo único que tienes que hacer manualmente es añadir primero el archivo de clave privada `%s` a Termius.
|
5
lang/app/texts/termiusSetup_fr.md
Normal file
5
lang/app/texts/termiusSetup_fr.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Installation de Termius
|
||||
|
||||
Pour utiliser Termius comme terminal, tu peux le connecter au pont SSH de XPipe. Cela peut fonctionner automatiquement une fois que la clé ssh du pont local a été ajoutée à Termius.
|
||||
|
||||
La seule chose que tu dois faire manuellement est d'ajouter le fichier de clé privée `%s` à Termius d'abord.
|
5
lang/app/texts/termiusSetup_it.md
Normal file
5
lang/app/texts/termiusSetup_it.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Configurazione di Termius
|
||||
|
||||
Per utilizzare Termius come terminale, puoi collegarlo al bridge SSH di XPipe. Questo può funzionare automaticamente una volta che la chiave ssh del bridge locale è stata aggiunta a Termius.
|
||||
|
||||
L'unica cosa che devi fare manualmente è aggiungere il file della chiave privata `%s` a Termius.
|
5
lang/app/texts/termiusSetup_ja.md
Normal file
5
lang/app/texts/termiusSetup_ja.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# テルミウスのセットアップ
|
||||
|
||||
Termiusをターミナルとして使用するには、XPipe SSHブリッジに接続する。ローカルブリッジのsshキーがTermiusに追加されれば自動的に動作する。
|
||||
|
||||
唯一手動で行う必要があるのは、最初に秘密鍵ファイル`%s`をTermiusに追加することだ。
|
5
lang/app/texts/termiusSetup_nl.md
Normal file
5
lang/app/texts/termiusSetup_nl.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Termius installatie
|
||||
|
||||
Om Termius als terminal te gebruiken, kun je het verbinden met de XPipe SSH bridge. Dit kan automatisch werken zodra de lokale bridge ssh sleutel is toegevoegd aan Termius.
|
||||
|
||||
Het enige dat je handmatig moet doen is eerst het private key bestand `%s` toevoegen aan Termius.
|
5
lang/app/texts/termiusSetup_pt.md
Normal file
5
lang/app/texts/termiusSetup_pt.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Configuração do Termius
|
||||
|
||||
Para usar o Termius como terminal, podes ligá-lo à bridge SSH XPipe. Isto pode funcionar automaticamente uma vez que a chave ssh da ponte local tenha sido adicionada ao Termius.
|
||||
|
||||
A única coisa que tens de fazer manualmente é adicionar o ficheiro de chave privada `%s` ao Termius primeiro.
|
5
lang/app/texts/termiusSetup_ru.md
Normal file
5
lang/app/texts/termiusSetup_ru.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Настройка Термиуса
|
||||
|
||||
Чтобы использовать Termius в качестве терминала, ты можешь подключить его к SSH-мосту XPipe. Это может работать автоматически, как только локальный ssh-ключ моста будет добавлен в Termius.
|
||||
|
||||
Единственное, что тебе придется сделать вручную, - это сначала добавить в Termius файл закрытого ключа `%s`.
|
5
lang/app/texts/termiusSetup_tr.md
Normal file
5
lang/app/texts/termiusSetup_tr.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Termius kurulumu
|
||||
|
||||
Termius'u terminaliniz olarak kullanmak için XPipe SSH köprüsüne bağlayabilirsiniz. Yerel köprü ssh anahtarı Termius'a eklendiğinde bu otomatik olarak çalışabilir.
|
||||
|
||||
Manuel olarak yapmanız gereken tek şey, önce `%s` özel anahtar dosyasını Termius'a eklemektir.
|
5
lang/app/texts/termiusSetup_zh.md
Normal file
5
lang/app/texts/termiusSetup_zh.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Termius 设置
|
||||
|
||||
要将 Termius 作为终端使用,可以将其连接到 XPipe SSH 网桥。一旦本地网桥的 ssh 密钥添加到 Termius,它就会自动运行。
|
||||
|
||||
唯一需要手动操作的是先将私钥文件 `%s` 添加到 Termius。
|
5
lang/app/texts/xshellSetup_da.md
Normal file
5
lang/app/texts/xshellSetup_da.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Xshell setup
|
||||
|
||||
For at bruge Xshell som din terminal kan du forbinde den til XPipe SSH-broen. Det kan ske automatisk, når den lokale ssh-nøgle til broen er blevet føjet til Xshell med det korrekte navn.
|
||||
|
||||
Det eneste, du skal gøre manuelt, er at tilføje den private nøglefil `%s` til Xshell med det faste navn `%s`.
|
5
lang/app/texts/xshellSetup_de.md
Normal file
5
lang/app/texts/xshellSetup_de.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Xshell-Einrichtung
|
||||
|
||||
Um Xshell als Terminal zu verwenden, kannst du es mit der XPipe SSH-Bridge verbinden. Das kann automatisch funktionieren, sobald der lokale Bridge-Ssh-Schlüssel mit dem richtigen Namen zu Xshell hinzugefügt wurde.
|
||||
|
||||
Das Einzige, was du manuell tun musst, ist, die private Schlüsseldatei `%s` mit dem festen Namen `%s` zu Xshell hinzuzufügen.
|
5
lang/app/texts/xshellSetup_en.md
Normal file
5
lang/app/texts/xshellSetup_en.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Xshell setup
|
||||
|
||||
To use Xshell as your terminal, you can connect it to the XPipe SSH bridge. This can work automatically once the local bridge ssh key has been added to Xshell with the correct name.
|
||||
|
||||
The only thing you have to do manually is to add the private key file `%s` to Xshell with the fixed name `%s`.
|
5
lang/app/texts/xshellSetup_es.md
Normal file
5
lang/app/texts/xshellSetup_es.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Configuración de Xshell
|
||||
|
||||
Para utilizar Xshell como terminal, puedes conectarlo al puente SSH de XPipe. Esto puede funcionar automáticamente una vez que la clave ssh del puente local se haya añadido a Xshell con el nombre correcto.
|
||||
|
||||
Lo único que tienes que hacer manualmente es añadir el archivo de clave privada `%s` a Xshell con el nombre fijo `%s`.
|
5
lang/app/texts/xshellSetup_fr.md
Normal file
5
lang/app/texts/xshellSetup_fr.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Configuration de Xshell
|
||||
|
||||
Pour utiliser Xshell comme terminal, tu peux le connecter au pont SSH de XPipe. Cela peut fonctionner automatiquement une fois que la clé ssh du pont local a été ajoutée à Xshell avec le nom correct.
|
||||
|
||||
La seule chose que tu dois faire manuellement est d'ajouter le fichier de clé privée `%s` à Xshell avec le nom fixe `%s`.
|
5
lang/app/texts/xshellSetup_it.md
Normal file
5
lang/app/texts/xshellSetup_it.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Configurazione di Xshell
|
||||
|
||||
Per utilizzare Xshell come terminale, puoi collegarlo al bridge SSH di XPipe. Questo può funzionare automaticamente una volta che la chiave ssh del bridge locale è stata aggiunta a Xshell con il nome corretto.
|
||||
|
||||
L'unica cosa che devi fare manualmente è aggiungere il file della chiave privata `%s` a Xshell con il nome fisso `%s`.
|
5
lang/app/texts/xshellSetup_ja.md
Normal file
5
lang/app/texts/xshellSetup_ja.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Xshellのセットアップ
|
||||
|
||||
Xshellをターミナルとして使用するには、XPipe SSHブリッジに接続する。ローカルブリッジのsshキーが正しい名前でXshellに追加されれば、自動的に動作する。
|
||||
|
||||
手動で行う必要があるのは、秘密鍵ファイル`%s`を固定名`%s`でXshellに追加することだけだ。
|
5
lang/app/texts/xshellSetup_nl.md
Normal file
5
lang/app/texts/xshellSetup_nl.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Xshell instelling
|
||||
|
||||
Om Xshell als terminal te gebruiken kun je het verbinden met de XPipe SSH bridge. Dit kan automatisch werken zodra de lokale bridge ssh key is toegevoegd aan Xshell met de juiste naam.
|
||||
|
||||
Het enige dat je handmatig moet doen is het private key bestand `%s` toevoegen aan Xshell met de vaste naam `%s`.
|
5
lang/app/texts/xshellSetup_pt.md
Normal file
5
lang/app/texts/xshellSetup_pt.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Configuração do Xshell
|
||||
|
||||
Para utilizar o Xshell como o teu terminal, podes ligá-lo à ponte SSH XPipe. Isto pode funcionar automaticamente quando a chave ssh da ponte local tiver sido adicionada ao Xshell com o nome correto.
|
||||
|
||||
A única coisa que tens de fazer manualmente é adicionar o ficheiro de chave privada `%s` ao Xshell com o nome fixo `%s`.
|
5
lang/app/texts/xshellSetup_ru.md
Normal file
5
lang/app/texts/xshellSetup_ru.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Xshell setup
|
||||
|
||||
Чтобы использовать Xshell в качестве терминала, ты можешь подключить его к SSH-мосту XPipe. Это может работать автоматически, как только локальный ssh-ключ моста будет добавлен в Xshell с правильным именем.
|
||||
|
||||
Единственное, что тебе придется сделать вручную, - это добавить файл закрытого ключа `%s` в Xshell с фиксированным именем `%s`.
|
5
lang/app/texts/xshellSetup_tr.md
Normal file
5
lang/app/texts/xshellSetup_tr.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Xshell kurulumu
|
||||
|
||||
Xshell'i terminaliniz olarak kullanmak için XPipe SSH köprüsüne bağlayabilirsiniz. Yerel köprü ssh anahtarı Xshell'e doğru isimle eklendiğinde bu otomatik olarak çalışabilir.
|
||||
|
||||
Manuel olarak yapmanız gereken tek şey `%s` özel anahtar dosyasını `%s` sabit adıyla Xshell'e eklemektir.
|
5
lang/app/texts/xshellSetup_zh.md
Normal file
5
lang/app/texts/xshellSetup_zh.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Xshell 设置
|
||||
|
||||
要将 Xshell 用作终端,可以将其连接到 XPipe SSH 网桥。一旦本地桥接器的 ssh 密钥以正确的名称添加到 Xshell,它就会自动运行。
|
||||
|
||||
唯一需要手动操作的是将私钥文件 `%s` 添加到 Xshell,并使用固定名称 `%s`。
|
Loading…
Reference in a new issue