@flowfuse/driver-localfs 2.22.2-60aa65d-202510141224.0 → 2.22.2-958d1af-202510230848.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release-publish.yml +1 -1
- package/localfs.js +61 -39
- package/package.json +2 -2
|
@@ -9,7 +9,7 @@ jobs:
|
|
|
9
9
|
runs-on: ubuntu-latest
|
|
10
10
|
steps:
|
|
11
11
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
12
|
-
- uses: actions/setup-node@
|
|
12
|
+
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
|
13
13
|
with:
|
|
14
14
|
node-version: 18
|
|
15
15
|
- run: npm ci --omit=dev
|
package/localfs.js
CHANGED
|
@@ -207,20 +207,21 @@ async function getProjectList (driver) {
|
|
|
207
207
|
}
|
|
208
208
|
]
|
|
209
209
|
})
|
|
210
|
-
|
|
210
|
+
for (const project of projects) {
|
|
211
211
|
const projectSettings = {}
|
|
212
212
|
// Remap the project settings to make them accessible
|
|
213
|
-
project.ProjectSettings
|
|
213
|
+
for (const ps of project.ProjectSettings) {
|
|
214
214
|
projectSettings[ps.key] = ps.value
|
|
215
|
-
}
|
|
215
|
+
}
|
|
216
216
|
driver._usedPorts.add(projectSettings.port)
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
const cachedProject = await driver._projects.get(project.id)
|
|
218
|
+
if (cachedProject === undefined) {
|
|
219
|
+
await driver._projects.set(project.id, {
|
|
219
220
|
state: 'unknown'
|
|
220
|
-
}
|
|
221
|
+
})
|
|
221
222
|
}
|
|
222
223
|
project._settings = projectSettings
|
|
223
|
-
}
|
|
224
|
+
}
|
|
224
225
|
return projects
|
|
225
226
|
}
|
|
226
227
|
|
|
@@ -233,11 +234,11 @@ async function getMQTTAgentList (driver) {
|
|
|
233
234
|
})
|
|
234
235
|
|
|
235
236
|
agents.concat(teamBrokerAgents)
|
|
236
|
-
|
|
237
|
+
for (const agent of agents) {
|
|
237
238
|
if (agent.Team && agent.settings.port) {
|
|
238
239
|
driver._usedAgentPorts.add(agent.settings.port)
|
|
239
240
|
}
|
|
240
|
-
}
|
|
241
|
+
}
|
|
241
242
|
|
|
242
243
|
return agents
|
|
243
244
|
}
|
|
@@ -246,11 +247,11 @@ async function checkExistingProjects (driver) {
|
|
|
246
247
|
logger.debug('[localfs] Checking instance status')
|
|
247
248
|
|
|
248
249
|
const projects = await getProjectList(driver)
|
|
249
|
-
|
|
250
|
+
for (const project of projects) {
|
|
250
251
|
const projectSettings = project._settings
|
|
251
252
|
// Suspended projects don't get restarted
|
|
252
253
|
if (project.state === 'suspended') {
|
|
253
|
-
|
|
254
|
+
continue
|
|
254
255
|
}
|
|
255
256
|
|
|
256
257
|
logger.debug(`[localfs] Instance ${project.id} port ${projectSettings.port}`)
|
|
@@ -269,9 +270,9 @@ async function checkExistingProjects (driver) {
|
|
|
269
270
|
logger.warn(`[localfs] Instance ${project.id} expected on port ${projectSettings.port}. Found ${info.id}`)
|
|
270
271
|
// TODO should do something here...
|
|
271
272
|
} else {
|
|
272
|
-
driver._projects
|
|
273
|
+
await driver._projects.set(project.id, {
|
|
273
274
|
state: 'started'
|
|
274
|
-
}
|
|
275
|
+
})
|
|
275
276
|
}
|
|
276
277
|
} catch (err) {
|
|
277
278
|
logger.info(`Starting instance ${project.id} on port ${projectSettings.port}`)
|
|
@@ -280,20 +281,20 @@ async function checkExistingProjects (driver) {
|
|
|
280
281
|
|
|
281
282
|
const pid = await startProject(driver._app, project, projectStack, projectSettings.path, projectSettings.port)
|
|
282
283
|
await project.updateSetting('pid', pid)
|
|
283
|
-
driver._projects
|
|
284
|
+
await driver._projects.set(project.id, {
|
|
284
285
|
state: 'started'
|
|
285
|
-
}
|
|
286
|
+
})
|
|
286
287
|
}
|
|
287
|
-
}
|
|
288
|
+
}
|
|
288
289
|
}
|
|
289
290
|
|
|
290
291
|
async function checkExistingMQTTAgents (driver) {
|
|
291
292
|
const brokers = await getMQTTAgentList(driver)
|
|
292
293
|
|
|
293
|
-
|
|
294
|
+
for (const broker of brokers) {
|
|
294
295
|
if (broker.Team) {
|
|
295
296
|
if (broker.state !== 'running') {
|
|
296
|
-
|
|
297
|
+
continue
|
|
297
298
|
}
|
|
298
299
|
|
|
299
300
|
try {
|
|
@@ -307,7 +308,7 @@ async function checkExistingMQTTAgents (driver) {
|
|
|
307
308
|
launchMQTTAgent(broker, driver)
|
|
308
309
|
}
|
|
309
310
|
}
|
|
310
|
-
}
|
|
311
|
+
}
|
|
311
312
|
}
|
|
312
313
|
|
|
313
314
|
async function launchMQTTAgent (broker, driver) {
|
|
@@ -391,7 +392,12 @@ module.exports = {
|
|
|
391
392
|
init: async (app, options) => {
|
|
392
393
|
this._app = app
|
|
393
394
|
this._options = options
|
|
394
|
-
this._projects = {}
|
|
395
|
+
this._projects = app.caches.getCache('driver-localfs-projects') // {}
|
|
396
|
+
// need to clear redis as this should not be keeping state across restarts
|
|
397
|
+
const _projectKeys = await this._projects.keys()
|
|
398
|
+
for (const k of _projectKeys) {
|
|
399
|
+
this._projects.del(k)
|
|
400
|
+
}
|
|
395
401
|
this._usedPorts = new Set()
|
|
396
402
|
this._usedAgentPorts = new Set()
|
|
397
403
|
// TODO need a better way to find this location?
|
|
@@ -459,9 +465,9 @@ module.exports = {
|
|
|
459
465
|
this._usedPorts.add(port)
|
|
460
466
|
}
|
|
461
467
|
|
|
462
|
-
this._projects
|
|
468
|
+
await this._projects.set(project.id, {
|
|
463
469
|
state: 'starting'
|
|
464
|
-
}
|
|
470
|
+
})
|
|
465
471
|
|
|
466
472
|
await project.updateSettings({
|
|
467
473
|
path: directory,
|
|
@@ -483,7 +489,9 @@ module.exports = {
|
|
|
483
489
|
setTimeout(async () => {
|
|
484
490
|
logger.debug(`PID ${pid}, port, ${port}, directory, ${directory}`)
|
|
485
491
|
await project.updateSetting('pid', pid)
|
|
486
|
-
this._projects
|
|
492
|
+
const cachedProject = await this._projects.get(project.id)
|
|
493
|
+
cachedProject.state = 'started'
|
|
494
|
+
await this._projects.set(project.id, cachedProject)
|
|
487
495
|
resolve()
|
|
488
496
|
}, 1000)
|
|
489
497
|
})
|
|
@@ -496,7 +504,9 @@ module.exports = {
|
|
|
496
504
|
*/
|
|
497
505
|
stop: async (project) => {
|
|
498
506
|
const projectSettings = await project.getAllSettings()
|
|
499
|
-
this._projects
|
|
507
|
+
const cachedProject = await this._projects.get(project.id)
|
|
508
|
+
cachedProject.state = 'suspended'
|
|
509
|
+
await this._projects.set(project.id, cachedProject)
|
|
500
510
|
stopProject(this._app, project, projectSettings)
|
|
501
511
|
},
|
|
502
512
|
|
|
@@ -518,7 +528,7 @@ module.exports = {
|
|
|
518
528
|
}, 5000)
|
|
519
529
|
|
|
520
530
|
this._usedPorts.delete(projectSettings.port)
|
|
521
|
-
|
|
531
|
+
await this._projects.del(project.id)
|
|
522
532
|
},
|
|
523
533
|
/**
|
|
524
534
|
* Retrieves details of a project's container
|
|
@@ -526,14 +536,15 @@ module.exports = {
|
|
|
526
536
|
* @return {Object}
|
|
527
537
|
*/
|
|
528
538
|
details: async (project) => {
|
|
529
|
-
|
|
539
|
+
const cachedProject = await this._projects.get(project.id)
|
|
540
|
+
if (cachedProject === undefined) {
|
|
530
541
|
return { state: 'unknown' }
|
|
531
542
|
}
|
|
532
|
-
if (
|
|
543
|
+
if (cachedProject.state === 'suspended') {
|
|
533
544
|
// We should only poll the launcher if we think it is running.
|
|
534
545
|
// Otherwise, return our cached state
|
|
535
546
|
return {
|
|
536
|
-
state:
|
|
547
|
+
state: cachedProject.state
|
|
537
548
|
}
|
|
538
549
|
}
|
|
539
550
|
const port = await project.getSetting('port')
|
|
@@ -574,7 +585,8 @@ module.exports = {
|
|
|
574
585
|
* @param {Project} project - the project model instance
|
|
575
586
|
*/
|
|
576
587
|
startFlows: async (project) => {
|
|
577
|
-
|
|
588
|
+
const cachedProject = await this._projects.get(project.id)
|
|
589
|
+
if (cachedProject === undefined) {
|
|
578
590
|
throw new Error('Instance cannot start flows')
|
|
579
591
|
}
|
|
580
592
|
const port = await project.getSetting('port')
|
|
@@ -590,7 +602,8 @@ module.exports = {
|
|
|
590
602
|
* @return {forge.Status}
|
|
591
603
|
*/
|
|
592
604
|
stopFlows: async (project) => {
|
|
593
|
-
|
|
605
|
+
const cachedProject = await this._projects.get(project.id)
|
|
606
|
+
if (cachedProject === undefined) {
|
|
594
607
|
throw new Error('Instance cannot stop flows')
|
|
595
608
|
}
|
|
596
609
|
const port = await project.getSetting('port')
|
|
@@ -606,7 +619,8 @@ module.exports = {
|
|
|
606
619
|
* @return {forge.Status}
|
|
607
620
|
*/
|
|
608
621
|
restartFlows: async (project) => {
|
|
609
|
-
|
|
622
|
+
const cachedProject = await this._projects.get(project.id)
|
|
623
|
+
if (cachedProject === undefined) {
|
|
610
624
|
throw new Error('Instance cannot restart flows')
|
|
611
625
|
}
|
|
612
626
|
const port = await project.getSetting('port')
|
|
@@ -643,7 +657,8 @@ module.exports = {
|
|
|
643
657
|
* @return {array} logs
|
|
644
658
|
*/
|
|
645
659
|
logs: async (project) => {
|
|
646
|
-
|
|
660
|
+
const cachedProject = await this._projects.get(project.id)
|
|
661
|
+
if (cachedProject === undefined) {
|
|
647
662
|
throw new Error('Cannot get instance logs')
|
|
648
663
|
}
|
|
649
664
|
const port = await project.getSetting('port')
|
|
@@ -695,7 +710,8 @@ module.exports = {
|
|
|
695
710
|
|
|
696
711
|
// Static Assets API
|
|
697
712
|
listFiles: async (instance, filePath) => {
|
|
698
|
-
|
|
713
|
+
const cachedProject = await this._projects.get(instance.id)
|
|
714
|
+
if (cachedProject === undefined) {
|
|
699
715
|
throw new Error('Cannot access instance files')
|
|
700
716
|
}
|
|
701
717
|
const fileUrl = await getStaticFileUrl(instance, filePath)
|
|
@@ -708,7 +724,8 @@ module.exports = {
|
|
|
708
724
|
},
|
|
709
725
|
|
|
710
726
|
updateFile: async (instance, filePath, update) => {
|
|
711
|
-
|
|
727
|
+
const cachedProject = await this._projects.get(instance.id)
|
|
728
|
+
if (cachedProject === undefined) {
|
|
712
729
|
throw new Error('Cannot access instance files')
|
|
713
730
|
}
|
|
714
731
|
const fileUrl = await getStaticFileUrl(instance, filePath)
|
|
@@ -723,7 +740,8 @@ module.exports = {
|
|
|
723
740
|
},
|
|
724
741
|
|
|
725
742
|
deleteFile: async (instance, filePath) => {
|
|
726
|
-
|
|
743
|
+
const cachedProject = await this._projects.get(instance.id)
|
|
744
|
+
if (cachedProject === undefined) {
|
|
727
745
|
throw new Error('Cannot access instance files')
|
|
728
746
|
}
|
|
729
747
|
const fileUrl = await getStaticFileUrl(instance, filePath)
|
|
@@ -735,7 +753,8 @@ module.exports = {
|
|
|
735
753
|
}
|
|
736
754
|
},
|
|
737
755
|
createDirectory: async (instance, filePath, directoryName) => {
|
|
738
|
-
|
|
756
|
+
const cachedProject = await this._projects.get(instance.id)
|
|
757
|
+
if (cachedProject === undefined) {
|
|
739
758
|
throw new Error('Cannot access instance files')
|
|
740
759
|
}
|
|
741
760
|
const fileUrl = await getStaticFileUrl(instance, filePath)
|
|
@@ -749,7 +768,8 @@ module.exports = {
|
|
|
749
768
|
}
|
|
750
769
|
},
|
|
751
770
|
uploadFile: async (instance, filePath, fileBuffer) => {
|
|
752
|
-
|
|
771
|
+
const cachedProject = await this._projects.get(instance.id)
|
|
772
|
+
if (cachedProject === undefined) {
|
|
753
773
|
throw new Error('Cannot access instance files')
|
|
754
774
|
}
|
|
755
775
|
const form = new FormData()
|
|
@@ -819,7 +839,8 @@ module.exports = {
|
|
|
819
839
|
}
|
|
820
840
|
},
|
|
821
841
|
resources: async (project) => {
|
|
822
|
-
|
|
842
|
+
const cachedProject = await this._projects.get(project.id)
|
|
843
|
+
if (cachedProject === undefined) {
|
|
823
844
|
throw new Error('Cannot get instance resources')
|
|
824
845
|
}
|
|
825
846
|
const port = await project.getSetting('port')
|
|
@@ -835,7 +856,8 @@ module.exports = {
|
|
|
835
856
|
}
|
|
836
857
|
},
|
|
837
858
|
resourcesStream: async (project, socket) => {
|
|
838
|
-
|
|
859
|
+
const cachedProject = await this._projects.get(project.id)
|
|
860
|
+
if (cachedProject === undefined) {
|
|
839
861
|
throw new Error('Cannot get instance resources')
|
|
840
862
|
}
|
|
841
863
|
const port = await project.getSetting('port')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowfuse/driver-localfs",
|
|
3
|
-
"version": "2.22.2-
|
|
3
|
+
"version": "2.22.2-958d1af-202510230848.0",
|
|
4
4
|
"description": "Local Filesystem FlowFuse Project driver",
|
|
5
5
|
"main": "localfs.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"license": "Apache-2.0",
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@flowfuse/mqtt-schema-agent": "^1.0.0",
|
|
25
|
-
"@flowfuse/nr-launcher": "2.22.2-
|
|
25
|
+
"@flowfuse/nr-launcher": "2.22.2-18a4111-202510230816.0",
|
|
26
26
|
"form-data": "^4.0.0",
|
|
27
27
|
"got": "^11.8.5",
|
|
28
28
|
"semver": "~7.6.0",
|