Initiate safer boot sequence on upgrades
parent
2d51b2d4c2
commit
61ba3398ad
|
@ -19,10 +19,6 @@ export async function listCommands(): Promise<{ [key: string]: CommandDef }> {
|
|||
return syscall("system.listCommands");
|
||||
}
|
||||
|
||||
export async function getVersion(): Promise<string> {
|
||||
return syscall("system.getVersion");
|
||||
}
|
||||
|
||||
export async function reloadPlugs() {
|
||||
syscall("system.reloadPlugs");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Knex } from "knex";
|
||||
import { SysCallMapping } from "../system";
|
||||
|
||||
type Item = {
|
||||
export type Item = {
|
||||
page: string;
|
||||
key: string;
|
||||
value: any;
|
||||
|
|
|
@ -82,6 +82,19 @@ export class System<HookT> extends EventEmitter<SystemEvents<HookT>> {
|
|||
return Promise.resolve(syscall.callback(ctx, ...args));
|
||||
}
|
||||
|
||||
async localSyscall(
|
||||
contextPlugName: string,
|
||||
syscallName: string,
|
||||
args: any[]
|
||||
): Promise<any> {
|
||||
return this.syscallWithContext(
|
||||
// Mock the plug
|
||||
{ plug: { name: contextPlugName } as any },
|
||||
syscallName,
|
||||
args
|
||||
);
|
||||
}
|
||||
|
||||
async load(
|
||||
manifest: Manifest<HookT>,
|
||||
sandboxFactory: SandboxFactory<HookT>
|
||||
|
|
|
@ -46,13 +46,6 @@ functions:
|
|||
path: "./page.ts:deletePage"
|
||||
command:
|
||||
name: "Page: Delete"
|
||||
|
||||
editorInit:
|
||||
path: "./editor.ts:editorInit"
|
||||
env: client
|
||||
events:
|
||||
- plugs:loaded
|
||||
|
||||
# Backlinks
|
||||
indexLinks:
|
||||
path: "./page.ts:indexLinks"
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
import { get, set } from "@plugos/plugos-syscall/store";
|
||||
import { flashNotification } from "@silverbulletmd/plugos-silverbullet-syscall/editor";
|
||||
import {
|
||||
getVersion,
|
||||
invokeFunction,
|
||||
} from "@silverbulletmd/plugos-silverbullet-syscall/system";
|
||||
|
||||
export async function editorInit() {
|
||||
let currentVersion = await getVersion();
|
||||
console.log("Running version check", currentVersion);
|
||||
let lastVersion = await get("$silverBulletVersion");
|
||||
console.log("Last version", lastVersion);
|
||||
if (lastVersion !== currentVersion) {
|
||||
await flashNotification(
|
||||
"Version update detected, going to reload plugs..."
|
||||
);
|
||||
await set("$spaceIndexed", false);
|
||||
await set("$silverBulletVersion", currentVersion);
|
||||
invokeFunction("client", "updatePlugsCommand");
|
||||
} else {
|
||||
let spaceIndexed = await get("$spaceIndexed");
|
||||
console.log("Space indexed", spaceIndexed);
|
||||
if (!spaceIndexed) {
|
||||
await set("$spaceIndexed", true);
|
||||
await invokeFunction("client", "reindexSpaceCommand");
|
||||
// Resetting this, because part of the reindex will be to wipe this too
|
||||
await set("$silverBulletVersion", currentVersion);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -200,7 +200,6 @@ async function getBackLinks(pageName: string): Promise<BackLink[]> {
|
|||
export async function reindexCommand() {
|
||||
await flashNotification("Reindexing...");
|
||||
await invokeFunction("server", "reindexSpace");
|
||||
await storeSet("$spaceIndexed", true);
|
||||
await flashNotification("Reindexing done");
|
||||
}
|
||||
|
||||
|
@ -235,6 +234,7 @@ export async function reindexSpace() {
|
|||
tree: parsed,
|
||||
});
|
||||
}
|
||||
console.log("Indexing completed!");
|
||||
}
|
||||
|
||||
export async function clearPageIndex(page: string) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import express, { Express } from "express";
|
||||
import { Manifest, SilverBulletHooks } from "@silverbulletmd/common/manifest";
|
||||
import { EndpointHook } from "@plugos/plugos/hooks/endpoint";
|
||||
import { readdir, readFile } from "fs/promises";
|
||||
import { readdir, readFile, rm } from "fs/promises";
|
||||
import { System } from "@plugos/plugos/system";
|
||||
import { DiskSpacePrimitives } from "@silverbulletmd/common/spaces/disk_space_primitives";
|
||||
import path from "path";
|
||||
|
@ -47,6 +47,8 @@ import {
|
|||
import { parseYamlSettings } from "@silverbulletmd/common/util";
|
||||
import { SpacePrimitives } from "@silverbulletmd/common/spaces/space_primitives";
|
||||
|
||||
import { version } from "./package.json";
|
||||
|
||||
const globalModules: any = JSON.parse(
|
||||
readFileSync(
|
||||
nodeModulesDir + "/node_modules/@silverbulletmd/web/dist/global.plug.json",
|
||||
|
@ -63,6 +65,10 @@ export type ServerOptions = {
|
|||
builtinPlugDir: string;
|
||||
password?: string;
|
||||
};
|
||||
|
||||
const storeVersionKey = "$silverBulletVersion";
|
||||
const indexRequiredKey = "$spaceIndexed";
|
||||
|
||||
export class ExpressServer {
|
||||
app: Express;
|
||||
system: System<SilverBulletHooks>;
|
||||
|
@ -196,9 +202,6 @@ export class ExpressServer {
|
|||
setInterval(() => {
|
||||
this.space.updatePageList().catch(console.error);
|
||||
}, 5000);
|
||||
|
||||
// Load plugs
|
||||
this.reloadPlugs().catch(console.error);
|
||||
}
|
||||
|
||||
rebuildMdExtensions() {
|
||||
|
@ -243,20 +246,78 @@ export class ExpressServer {
|
|||
}
|
||||
|
||||
async reloadPlugs() {
|
||||
// Version check
|
||||
let lastRunningVersion = await this.system.localSyscall(
|
||||
"core",
|
||||
"store.get",
|
||||
[storeVersionKey]
|
||||
);
|
||||
let upgrading = false;
|
||||
if (lastRunningVersion !== version) {
|
||||
upgrading = true;
|
||||
console.log("Version change detected!");
|
||||
console.log("Going to re-bootstrap with the builtin set of plugs...");
|
||||
console.log("First removing existing plug files...");
|
||||
const existingPlugFiles = (
|
||||
await this.spacePrimitives.fetchFileList()
|
||||
).filter((meta) => meta.name.startsWith(plugPrefix));
|
||||
for (let plugFile of existingPlugFiles) {
|
||||
await this.spacePrimitives.deleteFile(plugFile.name);
|
||||
}
|
||||
console.log("Now writing the default set of plugs...");
|
||||
await this.bootstrapBuiltinPlugs();
|
||||
await this.system.localSyscall("core", "store.set", [
|
||||
storeVersionKey,
|
||||
version,
|
||||
]);
|
||||
await this.system.localSyscall("core", "store.set", [
|
||||
"$spaceIndexed",
|
||||
false,
|
||||
]);
|
||||
}
|
||||
|
||||
await this.space.updatePageList();
|
||||
|
||||
let allPlugs = await this.space.listPlugs();
|
||||
|
||||
// Sanity check: are there any plugs at all? If not, let's put back the core set
|
||||
if (allPlugs.length === 0) {
|
||||
await this.bootstrapBuiltinPlugs();
|
||||
allPlugs = await this.space.listPlugs();
|
||||
}
|
||||
await this.system.unloadAll();
|
||||
console.log("Loading plugs");
|
||||
console.log(allPlugs);
|
||||
|
||||
console.log("Loading plugs", allPlugs);
|
||||
for (let plugName of allPlugs) {
|
||||
let { data } = await this.space.readAttachment(plugName, "string");
|
||||
await this.system.load(JSON.parse(data as string), createSandbox);
|
||||
}
|
||||
this.rebuildMdExtensions();
|
||||
|
||||
let corePlug = this.system.loadedPlugs.get("core");
|
||||
if (!corePlug) {
|
||||
console.error("Something went very wrong, 'core' plug not found");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're upgrading, update plugs from PLUGS file
|
||||
// This will automatically reinvoke an plugReload() call
|
||||
if (upgrading) {
|
||||
console.log("Now updating plugs");
|
||||
await corePlug.invoke("updatePlugs", []);
|
||||
}
|
||||
|
||||
// Do we need to reindex this space?
|
||||
if (
|
||||
!(await this.system.localSyscall("core", "store.get", [indexRequiredKey]))
|
||||
) {
|
||||
console.log("Now reindexing space...");
|
||||
await corePlug.invoke("reindexSpace", []);
|
||||
await this.system.localSyscall("core", "store.set", [
|
||||
indexRequiredKey,
|
||||
true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
async start() {
|
||||
|
@ -278,6 +339,9 @@ export class ExpressServer {
|
|||
await ensureFTSTable(this.db, "fts");
|
||||
await this.ensureAndLoadSettings();
|
||||
|
||||
// Load plugs
|
||||
this.reloadPlugs().catch(console.error);
|
||||
|
||||
// Serve static files (javascript, css, html)
|
||||
this.app.use("/", express.static(this.distDir));
|
||||
|
||||
|
|
|
@ -18,8 +18,5 @@ export function systemSyscalls(expressServer: ExpressServer): SysCallMapping {
|
|||
"system.reloadPlugs": async () => {
|
||||
return expressServer.reloadPlugs();
|
||||
},
|
||||
"system.getVersion": async () => {
|
||||
return version;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -224,13 +224,10 @@ export class Editor {
|
|||
// console.log("Navigating to anchor", pos);
|
||||
|
||||
// We're going to look up the anchor through a direct page store query...
|
||||
// TODO: This is a bit hacky, but it works for now
|
||||
let posLookup = await this.system.syscallWithContext(
|
||||
// Mock the "core" plug
|
||||
{ plug: { name: "core" } as any },
|
||||
"index.get",
|
||||
[pageName, `a:${pageName}:@${pos}`]
|
||||
);
|
||||
let posLookup = await this.system.localSyscall("core", "index.get", [
|
||||
pageName,
|
||||
`a:${pageName}:@${pos}`,
|
||||
]);
|
||||
|
||||
if (!posLookup) {
|
||||
return this.flashNotification(
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { SysCallMapping } from "@plugos/plugos/system";
|
||||
import type { Editor } from "../editor";
|
||||
import { CommandDef } from "../hooks/command";
|
||||
import { version } from "../package.json";
|
||||
|
||||
export function systemSyscalls(editor: Editor): SysCallMapping {
|
||||
return {
|
||||
|
@ -33,9 +32,6 @@ export function systemSyscalls(editor: Editor): SysCallMapping {
|
|||
}
|
||||
return allCommands;
|
||||
},
|
||||
"system.getVersion": async () => {
|
||||
return version;
|
||||
},
|
||||
"system.reloadPlugs": async () => {
|
||||
return editor.reloadPlugs();
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue