fix: plugins weren't stopped while updating
Massimo Melina committed
Jun 1, 2023 at 11:35 UTC
09aaf3204433c9a39b5a0914128029343aa9d873
3 files changed
+32
-13
admin/src/InstalledPlugins.ts
+2
-2
@@ -59,7 +59,7 @@ export default function InstalledPlugins({ updates }: { updates?: true }) {
59
color: 'success',
60
onClick: () =>
61
apiCall('set_plugin', { id, enabled: false }).then(() =>
62
- toast("Plugin is stopping", h(StopCircle, { color: 'warning' })))
62
+ toast("Plugin stopped", h(StopCircle, { color: 'warning' })))
63
} : {
64
icon: PlayCircle,
65
title: `Start ${id}`,
@@ -161,5 +161,5 @@ export function UpdateButton({ id, then }: { id: string, then: (id:string)=>void
161
162
export function startPlugin(id: string) {
163
return apiCall('set_plugin', { id, enabled: true }).then(() =>
164
- toast("Plugin is starting", h(PlayCircle, { color: 'success' })))
164
+ toast("Plugin started", h(PlayCircle, { color: 'success' })))
165
}
src/api.plugins.ts
+20
-9
@@ -6,13 +6,19 @@ import {
6
getAvailablePlugins,
7
getPluginConfigFields,
8
mapPlugins,
9
- Plugin, pluginsConfig,
10
- PATH as PLUGINS_PATH, isPluginRunning, enablePlugin, getPluginInfo, setPluginConfig
9
+ Plugin,
10
+ pluginsConfig,
11
+ PATH as PLUGINS_PATH,
12
+ enablePlugin,
13
+ getPluginInfo,
14
+ setPluginConfig,
15
+ findPluginByRepo,
16
+ isPluginEnabled
17
} from './plugins'
18
import _ from 'lodash'
19
import assert from 'assert'
14
-import { Callback, newObj, onOff, wait } from './misc'
15
-import { ApiHandlers, SendListReadable } from './apiMiddleware'
20
+import { Callback, newObj, onOff } from './misc'
21
+import { ApiError, ApiHandlers, SendListReadable } from './apiMiddleware'
22
import events from './events'
23
import { rm } from 'fs/promises'
24
import { downloadPlugin, getFolder2repo, getRepoInfo, readOnlinePlugin, searchPlugins } from './github'
@@ -59,10 +65,10 @@ const apis: ApiHandlers = {
65
66
async set_plugin({ id, enabled, config }) {
67
assert(id, 'id')
62
- if (enabled !== undefined)
63
- enablePlugin(id, enabled)
68
if (config)
65
- setPluginConfig(id, config)
69
+ setPluginConfig(id, config) // since we may wait the plugin to start, we save other changes first
70
+ if (enabled !== undefined)
71
+ await enablePlugin(id, enabled)
72
return {}
73
},
74
@@ -127,13 +133,18 @@ const apis: ApiHandlers = {
133
},
134
135
async update_plugin(pl) {
130
- await enablePlugin(pl.id, false, true)
136
+ const found = findPluginByRepo(pl.id) // github id !== local id
137
+ if (!found)
138
+ return new ApiError(404)
139
+ const enabled = isPluginEnabled(found.id)
140
+ await enablePlugin(found.id, false)
141
await downloadPlugin(pl.id, pl.branch, true)
142
+ enablePlugin(found.id, enabled).then() // don't wait, in case it fails to start
143
return {}
144
},
145
146
async uninstall_plugin({ id }) {
136
- await enablePlugin(id, false, true)
147
+ await enablePlugin(id, false)
148
await rm(PLUGINS_PATH + '/' + id, { recursive: true, force: true })
149
return {}
150
}
src/plugins.ts
+10
-2
@@ -40,13 +40,16 @@ export function isPluginRunning(id: string) {
40
return Boolean(plugins[id]?.started)
41
}
42
43
-export async function enablePlugin(id: string, state=true, waitForIt=false) {
43
+export function isPluginEnabled(id: string) {
44
+ return enablePlugins.get().includes(id)
45
+}
46
+
47
+export async function enablePlugin(id: string, state=true) {
48
enablePlugins.set( arr =>
49
arr.includes(id) === state ? arr
50
: state ? [...arr, id]
51
: arr.filter((x: string) => x !== id)
52
)
49
- if (!waitForIt) return
53
while (isPluginRunning(id) !== state)
54
await wait(500)
55
}
@@ -76,6 +79,11 @@ export function mapPlugins<T>(cb:(plugin:Readonly<Plugin>, pluginName:string)=>
79
}).filter(x => x !== undefined) as Exclude<T,undefined>[]
80
}
81
82
+export function findPluginByRepo<T>(repo: string) {
83
+ return _.find(plugins, pl => pl.getData()?.repo === repo)
84
+ || _.find(availablePlugins, { repo })
85
+}
86
+
87
export function getPluginConfigFields(id: string) {
88
return plugins[id]?.getData().config
89
}