mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-08-13 21:11:11 +00:00
Port incus features to lxc [stage]
This commit is contained in:
@@ -139,20 +139,20 @@ public class IncusCommandView extends CommandViewBase {
|
||||
}
|
||||
}
|
||||
|
||||
public ShellControl exec(String container, Integer uid, FilePath dir) {
|
||||
public ShellControl exec(String container, Integer uid, FilePath dir, ShellDialect shell) {
|
||||
return shellControl
|
||||
.subShell(createOpenFunction(container, uid, dir, false), createOpenFunction(container, uid, dir, true))
|
||||
.subShell(createOpenFunction(container, uid, dir, false, shell), createOpenFunction(container, uid, dir, true, shell))
|
||||
.withErrorFormatter(IncusCommandView::formatErrorMessage)
|
||||
.withExceptionConverter(IncusCommandView::convertException)
|
||||
.elevated(requiresElevation());
|
||||
}
|
||||
|
||||
private ShellOpenFunction createOpenFunction(String containerName, Integer uid, FilePath dir, boolean terminal) {
|
||||
private ShellOpenFunction createOpenFunction(String containerName, Integer uid, FilePath dir, boolean terminal, ShellDialect shell) {
|
||||
return new ShellOpenFunction() {
|
||||
@Override
|
||||
public CommandBuilder prepareWithoutInitCommand() {
|
||||
return execCommand(containerName, uid, dir, terminal)
|
||||
.add(ShellDialects.SH.getLaunchCommand().loginCommand());
|
||||
.add(shell.getLaunchCommand().loginCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,6 +7,8 @@ import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.*;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialect;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.store.FixedChildStore;
|
||||
import io.xpipe.core.store.StatefulDataStore;
|
||||
@@ -77,10 +79,11 @@ public class IncusContainerStore
|
||||
public ShellControl control(ShellControl parent) throws Exception {
|
||||
Integer uid = null;
|
||||
FilePath homeDir = null;
|
||||
if (identity != null && identity.unwrap().getUsername() != null) {
|
||||
try (var temp = new IncusCommandView(parent)
|
||||
.exec(containerName, null, null)
|
||||
.start()) {
|
||||
ShellDialect shell;
|
||||
try (var temp = new IncusCommandView(parent)
|
||||
.exec(containerName, null, null, ShellDialects.SH)
|
||||
.start()) {
|
||||
if (identity != null && identity.unwrap().getUsername() != null) {
|
||||
var passwd = PasswdFile.parse(temp);
|
||||
var username = identity.unwrap().getUsername();
|
||||
uid = passwd.getUidForUserIfPresent(username)
|
||||
@@ -89,9 +92,10 @@ public class IncusContainerStore
|
||||
homeDir = temp.command("eval echo ~" +username).readStdoutIfPossible().filter(s -> !s.isBlank())
|
||||
.map(FilePath::new).orElse(null);
|
||||
}
|
||||
shell = CommandSupport.isInPath(temp, "bash") ? ShellDialects.BASH : ShellDialects.SH;
|
||||
}
|
||||
|
||||
var sc = new IncusCommandView(parent).exec(containerName, uid, homeDir);
|
||||
var sc = new IncusCommandView(parent).exec(containerName, uid, homeDir, shell);
|
||||
sc.withSourceStore(IncusContainerStore.this);
|
||||
if (identity != null && identity.unwrap().getPassword() != null) {
|
||||
sc.setElevationHandler(new BaseElevationHandler(
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.CommandViewBase;
|
||||
import io.xpipe.core.process.*;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.*;
|
||||
@@ -86,12 +87,40 @@ public class LxdCommandView extends CommandViewBase {
|
||||
.readStdoutOrThrow();
|
||||
}
|
||||
|
||||
public String queryContainerState(String containerName) throws Exception {
|
||||
var states = listContainersAndStates();
|
||||
return states.getOrDefault(containerName, "?");
|
||||
}
|
||||
|
||||
public void start(String containerName) throws Exception {
|
||||
build(commandBuilder -> commandBuilder.add("start").addQuoted(containerName))
|
||||
.execute();
|
||||
}
|
||||
|
||||
public void stop(String containerName) throws Exception {
|
||||
build(commandBuilder -> commandBuilder.add("stop").addQuoted(containerName))
|
||||
.execute();
|
||||
}
|
||||
|
||||
public void pause(String containerName) throws Exception {
|
||||
build(commandBuilder -> commandBuilder.add("pause").addQuoted(containerName))
|
||||
.execute();
|
||||
}
|
||||
|
||||
public CommandControl console(String containerName) throws Exception {
|
||||
return build(commandBuilder -> commandBuilder.add("console").addQuoted(containerName));
|
||||
}
|
||||
|
||||
public CommandControl configEdit(String containerName) throws Exception {
|
||||
return build(commandBuilder -> commandBuilder.add("config", "edit").addQuoted(containerName));
|
||||
}
|
||||
|
||||
public List<DataStoreEntryRef<LxdContainerStore>> listContainers(DataStoreEntryRef<LxdCmdStore> store)
|
||||
throws Exception {
|
||||
return listContainersAndStates().entrySet().stream()
|
||||
.map(s -> {
|
||||
boolean running = s.getValue().toLowerCase(Locale.ROOT).equals("running");
|
||||
var c = new LxdContainerStore(store, s.getKey());
|
||||
var c = LxdContainerStore.builder().cmd(store).containerName(s.getKey()).build();
|
||||
var entry = DataStoreEntry.createNew(c.getContainerName(), c);
|
||||
entry.setStorePersistentState(ContainerStoreState.builder()
|
||||
.containerState(s.getValue())
|
||||
@@ -119,33 +148,37 @@ public class LxdCommandView extends CommandViewBase {
|
||||
}
|
||||
}
|
||||
|
||||
public ShellControl exec(String container) {
|
||||
public ShellControl exec(String container, Integer uid, FilePath dir, ShellDialect shell) {
|
||||
return shellControl
|
||||
.subShell(createOpenFunction(container, false), createOpenFunction(container, true))
|
||||
.subShell(createOpenFunction(container, uid, dir, shell, false), createOpenFunction(container, uid,dir, shell, true))
|
||||
.withErrorFormatter(LxdCommandView::formatErrorMessage)
|
||||
.withExceptionConverter(LxdCommandView::convertException)
|
||||
.elevated(requiresElevation());
|
||||
}
|
||||
|
||||
private ShellOpenFunction createOpenFunction(String containerName, boolean terminal) {
|
||||
private ShellOpenFunction createOpenFunction(String containerName, Integer uid, FilePath dir, ShellDialect shell, boolean terminal) {
|
||||
return new ShellOpenFunction() {
|
||||
@Override
|
||||
public CommandBuilder prepareWithoutInitCommand() {
|
||||
return execCommand(containerName, terminal)
|
||||
.add(ShellDialects.SH.getLaunchCommand().loginCommand());
|
||||
return execCommand(containerName, uid, dir, terminal)
|
||||
.add(shell.getLaunchCommand().loginCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandBuilder prepareWithInitCommand(@NonNull String command) {
|
||||
return execCommand(containerName, terminal).add(command);
|
||||
return execCommand(containerName, uid, dir , terminal).add(command);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public CommandBuilder execCommand(String containerName, boolean terminal) {
|
||||
return CommandBuilder.of()
|
||||
.add("lxc", "exec", terminal ? "-t" : "-T")
|
||||
.addQuoted(containerName)
|
||||
.add("--");
|
||||
public CommandBuilder execCommand(String containerName, Integer uid, FilePath dir, boolean terminal) {
|
||||
var c = CommandBuilder.of().add("lxc", "exec", terminal ? "-t" : "-T");
|
||||
if (uid != null) {
|
||||
c.add("--user").add(uid.toString());
|
||||
}
|
||||
if (dir != null) {
|
||||
c.add("--cwd").addFile(dir);
|
||||
}
|
||||
return c.addQuoted(containerName).add("--");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package io.xpipe.ext.system.lxd;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.ActionProvider;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.ext.base.store.StorePauseAction;
|
||||
import io.xpipe.ext.base.store.StoreRestartAction;
|
||||
import io.xpipe.ext.base.store.StoreStartAction;
|
||||
import io.xpipe.ext.base.store.StoreStopAction;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LxdContainerActionMenu implements ActionProvider {
|
||||
|
||||
@Override
|
||||
public BranchDataStoreCallSite<?> getBranchDataStoreCallSite() {
|
||||
return new BranchDataStoreCallSite<LxdContainerStore>() {
|
||||
|
||||
@Override
|
||||
public Class<LxdContainerStore> getApplicableClass() {
|
||||
return LxdContainerStore.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMajor(DataStoreEntryRef<LxdContainerStore> o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return AppI18n.observable("containerActions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return "mdi2p-package-variant-closed";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActionProvider> getChildren(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return List.of(
|
||||
new StoreStartAction(),
|
||||
new StoreStopAction(),
|
||||
new StorePauseAction(),
|
||||
new StoreRestartAction(),
|
||||
new LxdContainerConsoleAction(),
|
||||
new LxdContainerEditConfigAction(),
|
||||
new LxdContainerEditRunConfigAction());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package io.xpipe.ext.system.lxd;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.ActionProvider;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.terminal.TerminalLauncher;
|
||||
import io.xpipe.ext.system.incus.IncusCommandView;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.Value;
|
||||
|
||||
public class LxdContainerConsoleAction implements ActionProvider {
|
||||
|
||||
@Override
|
||||
public LeafDataStoreCallSite<?> getLeafDataStoreCallSite() {
|
||||
return new LeafDataStoreCallSite<LxdContainerStore>() {
|
||||
|
||||
@Override
|
||||
public ActionProvider.Action createAction(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return new Action(store.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<LxdContainerStore> getApplicableClass() {
|
||||
return LxdContainerStore.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return AppI18n.observable("serialConsole");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return "mdi2c-console";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresValidStore() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Value
|
||||
static class Action implements ActionProvider.Action {
|
||||
|
||||
DataStoreEntry store;
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
var d = (LxdContainerStore) store.getStore();
|
||||
var view = new IncusCommandView(d.getCmd().getStore().getHost().getStore().getOrStartSession());
|
||||
TerminalLauncher.open(store.getName(), view.console(d.getContainerName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package io.xpipe.ext.system.lxd;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.ActionProvider;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.terminal.TerminalLauncher;
|
||||
import io.xpipe.ext.system.incus.IncusCommandView;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.Value;
|
||||
|
||||
public class LxdContainerEditConfigAction implements ActionProvider {
|
||||
|
||||
@Override
|
||||
public LeafDataStoreCallSite<?> getLeafDataStoreCallSite() {
|
||||
return new LeafDataStoreCallSite<LxdContainerStore>() {
|
||||
|
||||
@Override
|
||||
public ActionProvider.Action createAction(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return new Action(store.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<LxdContainerStore> getApplicableClass() {
|
||||
return LxdContainerStore.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return AppI18n.observable("editConfiguration");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return "mdi2f-file-document-edit";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresValidStore() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Value
|
||||
static class Action implements ActionProvider.Action {
|
||||
|
||||
DataStoreEntry store;
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
var d = (LxdContainerStore) store.getStore();
|
||||
var view = new IncusCommandView(
|
||||
d.getCmd().getStore().getHost().getStore().getOrStartSession());
|
||||
TerminalLauncher.open(store.getName(), view.configEdit(d.getContainerName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package io.xpipe.ext.system.lxd;
|
||||
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.browser.file.BrowserFileOpener;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.ext.ActionProvider;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.Value;
|
||||
|
||||
public class LxdContainerEditRunConfigAction implements ActionProvider {
|
||||
|
||||
@Override
|
||||
public LeafDataStoreCallSite<?> getLeafDataStoreCallSite() {
|
||||
return new LeafDataStoreCallSite<LxdContainerStore>() {
|
||||
|
||||
@Override
|
||||
public ActionProvider.Action createAction(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return new Action(store.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<LxdContainerStore> getApplicableClass() {
|
||||
return LxdContainerStore.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return AppI18n.observable("editRunConfiguration");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIcon(DataStoreEntryRef<LxdContainerStore> store) {
|
||||
return "mdi2m-movie-edit";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresValidStore() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Value
|
||||
static class Action implements ActionProvider.Action {
|
||||
|
||||
DataStoreEntry store;
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
var d = (LxdContainerStore) store.getStore();
|
||||
var elevatedRef = ProcessControlProvider.get()
|
||||
.elevated(d.getCmd().getStore().getHost().get().ref());
|
||||
var file = new FilePath("/run/lxd/" + d.getContainerName() + "/lxc.conf");
|
||||
var model = BrowserFullSessionModel.DEFAULT.openFileSystemSync(
|
||||
elevatedRef, m -> file.getParent().toString(), null, true);
|
||||
var found = model.findFile(file.toString());
|
||||
if (found.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
AppLayoutModel.get().selectBrowser();
|
||||
BrowserFileOpener.openInTextEditor(model, found.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,19 @@ import io.xpipe.app.ext.ShellControlFunction;
|
||||
import io.xpipe.app.ext.ShellControlParentStoreFunction;
|
||||
import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.LicenseRequiredException;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.app.util.*;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialect;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.store.FixedChildStore;
|
||||
import io.xpipe.core.store.StatefulDataStore;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.ext.base.identity.IdentityValue;
|
||||
import io.xpipe.ext.base.store.PauseableStore;
|
||||
import io.xpipe.ext.base.store.StartableStore;
|
||||
import io.xpipe.ext.base.store.StoppableStore;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Value;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
@@ -25,10 +31,11 @@ import java.util.OptionalInt;
|
||||
@Jacksonized
|
||||
@Value
|
||||
@AllArgsConstructor
|
||||
public class LxdContainerStore implements ShellStore, FixedChildStore, StatefulDataStore<ContainerStoreState> {
|
||||
public class LxdContainerStore implements ShellStore, FixedChildStore, StatefulDataStore<ContainerStoreState>, StartableStore, StoppableStore, PauseableStore {
|
||||
|
||||
private final DataStoreEntryRef<LxdCmdStore> cmd;
|
||||
private final String containerName;
|
||||
IdentityValue identity;
|
||||
|
||||
@Override
|
||||
public Class<ContainerStoreState> getStateClass() {
|
||||
@@ -41,6 +48,9 @@ public class LxdContainerStore implements ShellStore, FixedChildStore, StatefulD
|
||||
Validators.isType(cmd, LxdCmdStore.class);
|
||||
cmd.checkComplete();
|
||||
Validators.nonNull(containerName);
|
||||
if (identity != null) {
|
||||
identity.checkComplete(false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,8 +68,30 @@ public class LxdContainerStore implements ShellStore, FixedChildStore, StatefulD
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellControl control(ShellControl parent) {
|
||||
var base = new LxdCommandView(parent).exec(containerName);
|
||||
public ShellControl control(ShellControl parent) throws Exception {
|
||||
Integer uid = null;
|
||||
FilePath homeDir = null;
|
||||
ShellDialect shell;
|
||||
try (var temp = new LxdCommandView(parent)
|
||||
.exec(containerName, null, null, ShellDialects.SH)
|
||||
.start()) {
|
||||
if (identity != null && identity.unwrap().getUsername() != null) {
|
||||
var passwd = PasswdFile.parse(temp);
|
||||
var username = identity.unwrap().getUsername();
|
||||
uid = passwd.getUidForUserIfPresent(username)
|
||||
.orElseThrow(() -> new IllegalArgumentException("User " + username + " not found"));
|
||||
homeDir = temp.command("eval echo ~" +username).readStdoutIfPossible().filter(s -> !s.isBlank())
|
||||
.map(FilePath::new).orElse(null);
|
||||
}
|
||||
shell = CommandSupport.isInPath(temp, "bash") ? ShellDialects.BASH : ShellDialects.SH;
|
||||
}
|
||||
|
||||
var base = new LxdCommandView(parent).exec(containerName, uid, homeDir, shell);
|
||||
if (identity != null && identity.unwrap().getPassword() != null) {
|
||||
base.setElevationHandler(new BaseElevationHandler(
|
||||
LxdContainerStore.this, identity.unwrap().getPassword())
|
||||
.orElse(base.getElevationHandler()));
|
||||
}
|
||||
return base.withSourceStore(LxdContainerStore.this)
|
||||
.onInit(shellControl -> {
|
||||
var s = getState().toBuilder()
|
||||
@@ -85,4 +117,39 @@ public class LxdContainerStore implements ShellStore, FixedChildStore, StatefulD
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private void refreshContainerState(ShellControl sc) throws Exception {
|
||||
var state = getState();
|
||||
var view = new LxdCommandView(sc);
|
||||
var displayState = view.queryContainerState(containerName);
|
||||
var running = "RUNNING".equals(displayState);
|
||||
var newState =
|
||||
state.toBuilder().containerState(displayState).running(running).build();
|
||||
setState(newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
var sc = getCmd().getStore().getHost().getStore().getOrStartSession();
|
||||
var view = new LxdCommandView(sc);
|
||||
view.start(containerName);
|
||||
refreshContainerState(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
var sc = getCmd().getStore().getHost().getStore().getOrStartSession();
|
||||
var view = new LxdCommandView(sc);
|
||||
view.stop(containerName);
|
||||
refreshContainerState(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() throws Exception {
|
||||
var sc = getCmd().getStore().getHost().getStore().getOrStartSession();
|
||||
var view = new LxdCommandView(sc);
|
||||
view.pause(containerName);
|
||||
refreshContainerState(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,10 @@ import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.app.util.ShellStoreFormat;
|
||||
import io.xpipe.app.util.SimpleValidator;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.ext.base.identity.IdentityChoice;
|
||||
import io.xpipe.ext.base.store.ShellStoreProvider;
|
||||
|
||||
import io.xpipe.ext.system.incus.IncusContainerStore;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -46,7 +48,7 @@ public class LxdContainerStoreProvider implements ShellStoreProvider {
|
||||
in a host shell of `%s` to open a shell into the container.
|
||||
""",
|
||||
new LxdCommandView(null)
|
||||
.execCommand(lxd.getContainerName(), true)
|
||||
.execCommand(lxd.getContainerName(), null, null,true)
|
||||
.buildSimple(),
|
||||
lxd.getCmd().getStore().getHost().get().getName());
|
||||
}
|
||||
@@ -59,8 +61,8 @@ public class LxdContainerStoreProvider implements ShellStoreProvider {
|
||||
|
||||
@Override
|
||||
public GuiDialog guiDialog(DataStoreEntry entry, Property<DataStore> store) {
|
||||
var val = new SimpleValidator();
|
||||
LxdContainerStore st = (LxdContainerStore) store.getValue();
|
||||
var identity = new SimpleObjectProperty<>(st.getIdentity());
|
||||
|
||||
var q = new OptionsBuilder()
|
||||
.name("host")
|
||||
@@ -73,8 +75,18 @@ public class LxdContainerStoreProvider implements ShellStoreProvider {
|
||||
.description("lxdContainerDescription")
|
||||
.addString(new SimpleObjectProperty<>(st.getContainerName()), false)
|
||||
.disable()
|
||||
.buildComp();
|
||||
return new GuiDialog(q, val);
|
||||
.sub(IdentityChoice.container(identity), identity)
|
||||
.bind(
|
||||
() -> {
|
||||
return LxdContainerStore.builder()
|
||||
.containerName(st.getContainerName())
|
||||
.cmd(st.getCmd())
|
||||
.identity(identity.getValue())
|
||||
.build();
|
||||
},
|
||||
store)
|
||||
.buildDialog();
|
||||
return q;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,7 +98,8 @@ public class LxdContainerStoreProvider implements ShellStoreProvider {
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> informationString(StoreSection section) {
|
||||
return ShellStoreFormat.shellStore(section, (ContainerStoreState s) -> s.getContainerState());
|
||||
return ShellStoreFormat.shellStore(
|
||||
section, (ContainerStoreState s) -> DataStoreFormatter.capitalize(s.getContainerState()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.xpipe.ext.system.incus.IncusContainerStoreProvider;
|
||||
import io.xpipe.ext.system.incus.IncusInstallStoreProvider;
|
||||
import io.xpipe.ext.system.incus.IncusScanProvider;
|
||||
import io.xpipe.ext.system.lxd.LxdCmdStoreProvider;
|
||||
import io.xpipe.ext.system.lxd.LxdContainerActionMenu;
|
||||
import io.xpipe.ext.system.lxd.LxdContainerStoreProvider;
|
||||
import io.xpipe.ext.system.lxd.LxdScanProvider;
|
||||
import io.xpipe.ext.system.podman.PodmanCmdStoreProvider;
|
||||
@@ -36,5 +37,6 @@ open module io.xpipe.ext.system {
|
||||
PodmanCmdStoreProvider;
|
||||
provides ActionProvider with
|
||||
IncusContainerActionMenu,
|
||||
LxdContainerActionMenu,
|
||||
PodmanContainerActionMenu;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user