This commit is contained in:
crschnick
2025-03-16 12:30:07 +00:00
parent e889a261a8
commit e2eef729a7
4 changed files with 52 additions and 110 deletions
@@ -7,10 +7,6 @@ import io.xpipe.core.store.*;
public interface ShellStore extends DataStore, FileSystemStore, ValidatableStore, SingletonSessionStore<ShellSession> {
default boolean isConnectionAttemptCostly() {
return false;
}
default ShellControl getOrStartSession() throws Exception {
var session = getSession();
if (session != null) {
@@ -6,35 +6,74 @@ import java.util.Optional;
public interface ShellTerminalInitCommand {
boolean isStatic();
default void runDumb(ShellControl shellControl) throws Exception {
throw new UnsupportedOperationException();
}
Optional<String> content(ShellControl sc);
default Optional<String> terminalContent(ShellControl shellControl) throws Exception {
throw new UnsupportedOperationException();
}
default boolean runInDumb() {
return false;
}
boolean canPotentiallyRunInDialect(ShellDialect dialect);
class Static implements ShellTerminalInitCommand {
default boolean runInTerminal() {
return false;
}
private final String content;
private final ShellDialect dialect;
interface Terminal extends ShellTerminalInitCommand {
public Static(String content, ShellDialect dialect) {
this.content = content;
this.dialect = dialect;
}
Optional<String> terminalContent(ShellControl shellControl) throws Exception;
@Override
public boolean isStatic() {
default boolean runInTerminal() {
return true;
}
}
class Simple implements ShellTerminalInitCommand {
@NonNull
private final String content;
private final ShellDialect dialect;
private final boolean dumb;
private final boolean terminal;
public Simple(@NonNull String content, ShellDialect dialect, boolean dumb, boolean terminal) {
this.content = content;
this.dialect = dialect;
this.dumb = dumb;
this.terminal = terminal;
}
@Override
public Optional<String> content(ShellControl sc) {
public void runDumb(ShellControl shellControl) throws Exception {
shellControl.executeSimpleCommand(content);
}
@Override
public Optional<String> terminalContent(ShellControl shellControl) {
return Optional.of(content);
}
@Override
public boolean runInDumb() {
return dumb;
}
@Override
public boolean canPotentiallyRunInDialect(ShellDialect dialect) {
return this.dialect == null || this.dialect.isCompatibleTo(dialect);
}
@Override
public boolean runInTerminal() {
return terminal;
}
}
}
@@ -1,8 +1,6 @@
package io.xpipe.ext.base.identity;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.ContextualFileReference;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.SecretRetrievalStrategy;
@@ -38,8 +36,6 @@ import java.io.IOException;
public interface SshIdentityStrategy {
default void checkComplete() throws ValidationException {}
boolean isConnectionAttemptCostly();
void prepareParent(ShellControl parent) throws Exception;
void buildCommand(CommandBuilder builder);
@@ -52,11 +48,6 @@ public interface SshIdentityStrategy {
@Value
class None implements SshIdentityStrategy {
@Override
public boolean isConnectionAttemptCostly() {
return false;
}
@Override
public void prepareParent(ShellControl parent) {}
@@ -75,11 +66,6 @@ public interface SshIdentityStrategy {
boolean forwardAgent;
@Override
public boolean isConnectionAttemptCostly() {
return false;
}
@Override
public void prepareParent(ShellControl parent) throws Exception {
SshIdentityStateManager.prepareSshAgent(parent);
@@ -101,11 +87,6 @@ public interface SshIdentityStrategy {
boolean forwardAgent;
@Override
public boolean isConnectionAttemptCostly() {
return false;
}
@Override
public void prepareParent(ShellControl parent) throws Exception {
if (!parent.getOsType().equals(OsType.WINDOWS)) {
@@ -176,11 +157,6 @@ public interface SshIdentityStrategy {
ContextualFileReference file;
SecretRetrievalStrategy password;
@Override
public boolean isConnectionAttemptCostly() {
return password.expectsQuery() && AppPrefs.get().dontCachePasswords().get();
}
public void checkComplete() throws ValidationException {
Validators.nonNull(file);
Validators.nonNull(password);
@@ -263,11 +239,6 @@ public interface SshIdentityStrategy {
boolean forwardAgent;
@Override
public boolean isConnectionAttemptCostly() {
return true;
}
@Override
public void prepareParent(ShellControl parent) throws Exception {
parent.requireLicensedFeature("gpgAgent");
@@ -297,11 +268,6 @@ public interface SshIdentityStrategy {
@AllArgsConstructor
class YubikeyPiv implements SshIdentityStrategy {
@Override
public boolean isConnectionAttemptCostly() {
return true;
}
private String getFile(ShellControl parent) throws Exception {
var file =
switch (parent.getOsType()) {
@@ -378,11 +344,6 @@ public interface SshIdentityStrategy {
String file;
@Override
public boolean isConnectionAttemptCostly() {
return true;
}
@Override
public void prepareParent(ShellControl parent) throws Exception {
parent.requireLicensedFeature("pkcs11Identity");
@@ -417,11 +378,6 @@ public interface SshIdentityStrategy {
boolean forwardAgent;
@Override
public boolean isConnectionAttemptCostly() {
return true;
}
@Override
public void prepareParent(ShellControl parent) {}
@@ -17,34 +17,6 @@ import java.util.*;
public class ScriptStoreSetup {
@Value
private static class GeneratedScriptCache {
UUID storeId;
List<Integer> scriptStoreHashes;
}
private static final Set<GeneratedScriptCache> generatedScriptCaches = new HashSet<>();
private static synchronized boolean hasGeneratedScriptsCached(UUID storeId, List<DataStoreEntryRef<SimpleScriptStore>> scripts) {
var c = generatedScriptCaches.stream().filter(e -> e.storeId.equals(storeId)).findFirst();
if (c.isEmpty()) {
return false;
}
return scripts.stream().allMatch(ref -> c.get().getScriptStoreHashes().contains(ref.getStore().hashCode()));
}
private static synchronized void cacheScripts(UUID storeId, List<DataStoreEntryRef<SimpleScriptStore>> scripts) {
var c = generatedScriptCaches.stream().filter(e -> e.storeId.equals(storeId)).findFirst();
if (c.isEmpty()) {
var newC = new GeneratedScriptCache(storeId, new ArrayList<>());
generatedScriptCaches.add(newC);
c = Optional.of(newC);
}
c.get().getScriptStoreHashes().addAll(scripts.stream().map(ref -> ref.getStore().hashCode()).toList());
}
public static ShellControl controlWithDefaultScripts(ShellControl pc) {
return controlWithScripts(pc, getEnabledScripts());
}
@@ -69,19 +41,7 @@ public class ScriptStoreSetup {
return pc;
}
var source = pc.getSourceStoreId();
if (source.isPresent()) {
var useCached = true || pc.getSourceStore().map(dataStore -> dataStore instanceof ShellStore s && s.isConnectionAttemptCostly()).orElse(false);
if (useCached) {
var cached = hasGeneratedScriptsCached(source.get(), initFlattened) && hasGeneratedScriptsCached(source.get(), bringFlattened);
if (cached) {
return pc;
}
}
}
initFlattened.forEach(s -> {
pc.withInitSnippet(new ShellTerminalInitCommand.Static(s.getStore().))
pc.withInitSnippet(new ShellTerminalInitCommand() {
@Override
public Optional<String> terminalContent(ShellControl shellControl) {
@@ -94,22 +54,13 @@ public class ScriptStoreSetup {
}
});
});
if (!bringFlattened.isEmpty() || source.isPresent()) {
if (!bringFlattened.isEmpty()) {
pc.withInitSnippet(new ShellTerminalInitCommand.Terminal() {
String dir;
@Override
public Optional<String> terminalContent(ShellControl shellControl) throws Exception {
if (source.isPresent()) {
cacheScripts(source.get(), initFlattened);
cacheScripts(source.get(), bringFlattened);
}
if (bringFlattened.isEmpty()) {
return Optional.empty();
}
if (dir == null) {
dir = initScriptsDirectory(shellControl, bringFlattened);
}