mirror of https://github.com/jetkvm/kvm.git
Better handle install and re-install lifecycle. Also display all the juicy bits about the plugin
This commit is contained in:
parent
2e24916331
commit
16064aa876
|
@ -19,7 +19,7 @@ type PluginInstall struct {
|
|||
ExtractedVersions map[string]string `json:"extracted_versions"`
|
||||
|
||||
manifest *PluginManifest
|
||||
runningVersion *string
|
||||
runningVersion string
|
||||
processManager *ProcessManager
|
||||
rpcServer *PluginRpcServer
|
||||
}
|
||||
|
@ -84,10 +84,7 @@ func (p *PluginInstall) ReconcileSubprocess() error {
|
|||
return fmt.Errorf("failed to get plugin manifest: %v", err)
|
||||
}
|
||||
|
||||
versionRunning := ""
|
||||
if p.runningVersion != nil {
|
||||
versionRunning = *p.runningVersion
|
||||
}
|
||||
versionRunning := p.runningVersion
|
||||
|
||||
versionShouldBeRunning := p.Version
|
||||
if !p.Enabled {
|
||||
|
@ -105,7 +102,7 @@ func (p *PluginInstall) ReconcileSubprocess() error {
|
|||
log.Printf("Stopping plugin %s running version %s", manifest.Name, versionRunning)
|
||||
p.processManager.Disable()
|
||||
p.processManager = nil
|
||||
p.runningVersion = nil
|
||||
p.runningVersion = ""
|
||||
err = p.rpcServer.Stop()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stop rpc server: %v", err)
|
||||
|
@ -146,7 +143,11 @@ func (p *PluginInstall) ReconcileSubprocess() error {
|
|||
})
|
||||
p.processManager.StartMonitor()
|
||||
p.processManager.Enable()
|
||||
p.runningVersion = &p.Version
|
||||
p.runningVersion = p.Version
|
||||
|
||||
// Clear out manifest so the new version gets pulled next time
|
||||
p.manifest = nil
|
||||
|
||||
log.Printf("Started plugin %s version %s", manifest.Name, p.Version)
|
||||
return nil
|
||||
}
|
||||
|
@ -155,7 +156,7 @@ func (p *PluginInstall) Shutdown() {
|
|||
if p.processManager != nil {
|
||||
p.processManager.Disable()
|
||||
p.processManager = nil
|
||||
p.runningVersion = nil
|
||||
p.runningVersion = ""
|
||||
}
|
||||
|
||||
if p.rpcServer != nil {
|
||||
|
|
|
@ -120,7 +120,6 @@ func RpcPluginExtract(filename string) (*PluginManifest, error) {
|
|||
}
|
||||
|
||||
func RpcPluginInstall(name string, version string) error {
|
||||
// TODO: find the plugin version in the plugins.json file
|
||||
pluginInstall, ok := pluginDatabase.Plugins[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("plugin not found: %s", name)
|
||||
|
@ -136,8 +135,6 @@ func RpcPluginInstall(name string, version string) error {
|
|||
return fmt.Errorf("plugin version not found: %s", version)
|
||||
}
|
||||
|
||||
// TODO: If there is a running plugin with the same name, stop it and start the new version
|
||||
|
||||
pluginInstall.Version = version
|
||||
pluginInstall.Enabled = true
|
||||
pluginDatabase.Plugins[name] = pluginInstall
|
||||
|
@ -151,7 +148,7 @@ func RpcPluginInstall(name string, version string) error {
|
|||
return fmt.Errorf("failed to start plugin %s: %v", name, err)
|
||||
}
|
||||
|
||||
// TODO: Determine if the old version should be removed
|
||||
// TODO: Determine if the old extract should be removed
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PluginStatus } from "@/hooks/stores";
|
||||
import { PluginStatus, usePluginStore } from "@/hooks/stores";
|
||||
import Modal from "@components/Modal";
|
||||
import AutoHeight from "@components/AutoHeight";
|
||||
import Card, { GridCard } from "@components/Card";
|
||||
|
@ -33,6 +33,8 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
|
|||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const {setIsPluginUploadModalOpen} = usePluginStore();
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(false);
|
||||
}, [plugin])
|
||||
|
@ -73,6 +75,11 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
|
|||
});
|
||||
}, [send, plugin, setOpen])
|
||||
|
||||
const uploadPlugin = useCallback(() => {
|
||||
setOpen(false);
|
||||
setIsPluginUploadModalOpen(true);
|
||||
}, [setIsPluginUploadModalOpen, setOpen])
|
||||
|
||||
return (
|
||||
<AutoHeight>
|
||||
<div className="mx-auto max-w-4xl px-4 transition-all duration-300 ease-in-out">
|
||||
|
@ -118,6 +125,30 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-[auto,1fr] gap-x-4 text-sm text-black dark:text-white">
|
||||
<span className="font-semibold">
|
||||
Name
|
||||
</span>
|
||||
<span>{plugin?.name}</span>
|
||||
|
||||
<span className="font-semibold">
|
||||
Active Version
|
||||
</span>
|
||||
<span>{plugin?.version}</span>
|
||||
|
||||
<span className="font-semibold">
|
||||
Description
|
||||
</span>
|
||||
<span>{plugin?.description}</span>
|
||||
|
||||
<span className="font-semibold">
|
||||
Homepage
|
||||
</span>
|
||||
<a href={plugin?.homepage} target="_blank" rel="noopener noreferrer" className="text-blue-600 hover:text-blue-800 dark:text-blue-500 dark:hover:text-blue-400">
|
||||
{plugin?.homepage}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="h-[1px] w-full bg-slate-800/10 dark:bg-slate-300/20" />
|
||||
|
||||
<div
|
||||
|
@ -129,15 +160,15 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
|
|||
{error && <p className="text-red-500 dark:text-red-400">{error}</p>}
|
||||
{plugin?.message && (
|
||||
<>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Plugin message:
|
||||
</p>
|
||||
<Card className={cx(
|
||||
"text-gray-500 dark:text-gray-400 p-4 border",
|
||||
plugin.status === "error" && "border-red-200 bg-red-50 text-red-800 dark:text-red-400",
|
||||
)}>
|
||||
{plugin.message}
|
||||
</Card>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Plugin message:
|
||||
</p>
|
||||
<Card className={cx(
|
||||
"text-gray-500 dark:text-gray-400 p-4 border",
|
||||
plugin.status === "error" && "border-red-200 bg-red-50 text-red-800 dark:text-red-400",
|
||||
)}>
|
||||
{plugin.message}
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 py-10">
|
||||
|
@ -154,6 +185,13 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
|
|||
}}
|
||||
>
|
||||
<div className="flex items-center w-full space-x-2">
|
||||
<Button
|
||||
size="MD"
|
||||
theme="primary"
|
||||
text="Upload New Version"
|
||||
disabled={loading}
|
||||
onClick={uploadPlugin}
|
||||
/>
|
||||
<Button
|
||||
size="MD"
|
||||
theme="blank"
|
||||
|
|
|
@ -67,7 +67,7 @@ export default function PluginList() {
|
|||
theme="light"
|
||||
text="Settings"
|
||||
onClick={() => {
|
||||
setConfiguringPlugin(plugin);
|
||||
setConfiguringPlugin(plugin.name);
|
||||
setPluginConfigureModalOpen(true);
|
||||
}}
|
||||
/>
|
||||
|
@ -85,7 +85,7 @@ export default function PluginList() {
|
|||
updatePlugins();
|
||||
}
|
||||
}}
|
||||
plugin={plugins.find(p => p.name == configuringPlugin?.name) ?? null}
|
||||
plugin={plugins.find(p => p.name == configuringPlugin) ?? null}
|
||||
/>
|
||||
|
||||
<div className="flex items-center gap-x-2">
|
||||
|
|
|
@ -45,6 +45,8 @@ function Dialog({ setOpen }: { setOpen: (open: boolean) => void }) {
|
|||
setPluginUploadFilename,
|
||||
pluginUploadManifest,
|
||||
setPluginUploadManifest,
|
||||
setConfiguringPlugin,
|
||||
setPluginConfigureModalOpen,
|
||||
} = usePluginStore();
|
||||
const [send] = useJsonRpc();
|
||||
const [extractError, setExtractError] = useState<string | null>(null);
|
||||
|
@ -112,7 +114,12 @@ function Dialog({ setOpen }: { setOpen: (open: boolean) => void }) {
|
|||
onInstall={() => {
|
||||
setOpen(false)
|
||||
setPluginUploadFilename(null)
|
||||
// TODO: Open plugin settings dialog
|
||||
if (pluginUploadManifest) {
|
||||
setConfiguringPlugin(pluginUploadManifest.name)
|
||||
setPluginConfigureModalOpen(true)
|
||||
}
|
||||
setPluginUploadManifest(null)
|
||||
setPluginUploadModalView("upload")
|
||||
}}
|
||||
onBack={() => {
|
||||
setPluginUploadModalView("upload")
|
||||
|
|
|
@ -562,8 +562,8 @@ interface PluginState {
|
|||
pluginConfigureModalOpen: boolean;
|
||||
setPluginConfigureModalOpen: (isOpen: boolean) => void;
|
||||
|
||||
configuringPlugin: PluginStatus | null;
|
||||
setConfiguringPlugin: (plugin: PluginStatus | null) => void;
|
||||
configuringPlugin: string | null;
|
||||
setConfiguringPlugin: (pluginName: string | null) => void;
|
||||
}
|
||||
|
||||
export const usePluginStore = create<PluginState>(set => ({
|
||||
|
|
Loading…
Reference in New Issue