Initiate safer boot sequence on upgrades
This commit is contained in:
parent
2d51b2d4c2
commit
61ba3398ad
@ -19,10 +19,6 @@ export async function listCommands(): Promise<{ [key: string]: CommandDef }> {
|
|||||||
return syscall("system.listCommands");
|
return syscall("system.listCommands");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getVersion(): Promise<string> {
|
|
||||||
return syscall("system.getVersion");
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function reloadPlugs() {
|
export async function reloadPlugs() {
|
||||||
syscall("system.reloadPlugs");
|
syscall("system.reloadPlugs");
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
import { SysCallMapping } from "../system";
|
import { SysCallMapping } from "../system";
|
||||||
|
|
||||||
type Item = {
|
export type Item = {
|
||||||
page: string;
|
page: string;
|
||||||
key: string;
|
key: string;
|
||||||
value: any;
|
value: any;
|
||||||
|
@ -82,6 +82,19 @@ export class System<HookT> extends EventEmitter<SystemEvents<HookT>> {
|
|||||||
return Promise.resolve(syscall.callback(ctx, ...args));
|
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(
|
async load(
|
||||||
manifest: Manifest<HookT>,
|
manifest: Manifest<HookT>,
|
||||||
sandboxFactory: SandboxFactory<HookT>
|
sandboxFactory: SandboxFactory<HookT>
|
||||||
|
@ -46,13 +46,6 @@ functions:
|
|||||||
path: "./page.ts:deletePage"
|
path: "./page.ts:deletePage"
|
||||||
command:
|
command:
|
||||||
name: "Page: Delete"
|
name: "Page: Delete"
|
||||||
|
|
||||||
editorInit:
|
|
||||||
path: "./editor.ts:editorInit"
|
|
||||||
env: client
|
|
||||||
events:
|
|
||||||
- plugs:loaded
|
|
||||||
|
|
||||||
# Backlinks
|
# Backlinks
|
||||||
indexLinks:
|
indexLinks:
|
||||||
path: "./page.ts: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() {
|
export async function reindexCommand() {
|
||||||
await flashNotification("Reindexing...");
|
await flashNotification("Reindexing...");
|
||||||
await invokeFunction("server", "reindexSpace");
|
await invokeFunction("server", "reindexSpace");
|
||||||
await storeSet("$spaceIndexed", true);
|
|
||||||
await flashNotification("Reindexing done");
|
await flashNotification("Reindexing done");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +234,7 @@ export async function reindexSpace() {
|
|||||||
tree: parsed,
|
tree: parsed,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
console.log("Indexing completed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function clearPageIndex(page: string) {
|
export async function clearPageIndex(page: string) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import express, { Express } from "express";
|
import express, { Express } from "express";
|
||||||
import { Manifest, SilverBulletHooks } from "@silverbulletmd/common/manifest";
|
import { Manifest, SilverBulletHooks } from "@silverbulletmd/common/manifest";
|
||||||
import { EndpointHook } from "@plugos/plugos/hooks/endpoint";
|
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 { System } from "@plugos/plugos/system";
|
||||||
import { DiskSpacePrimitives } from "@silverbulletmd/common/spaces/disk_space_primitives";
|
import { DiskSpacePrimitives } from "@silverbulletmd/common/spaces/disk_space_primitives";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
@ -47,6 +47,8 @@ import {
|
|||||||
import { parseYamlSettings } from "@silverbulletmd/common/util";
|
import { parseYamlSettings } from "@silverbulletmd/common/util";
|
||||||
import { SpacePrimitives } from "@silverbulletmd/common/spaces/space_primitives";
|
import { SpacePrimitives } from "@silverbulletmd/common/spaces/space_primitives";
|
||||||
|
|
||||||
|
import { version } from "./package.json";
|
||||||
|
|
||||||
const globalModules: any = JSON.parse(
|
const globalModules: any = JSON.parse(
|
||||||
readFileSync(
|
readFileSync(
|
||||||
nodeModulesDir + "/node_modules/@silverbulletmd/web/dist/global.plug.json",
|
nodeModulesDir + "/node_modules/@silverbulletmd/web/dist/global.plug.json",
|
||||||
@ -63,6 +65,10 @@ export type ServerOptions = {
|
|||||||
builtinPlugDir: string;
|
builtinPlugDir: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const storeVersionKey = "$silverBulletVersion";
|
||||||
|
const indexRequiredKey = "$spaceIndexed";
|
||||||
|
|
||||||
export class ExpressServer {
|
export class ExpressServer {
|
||||||
app: Express;
|
app: Express;
|
||||||
system: System<SilverBulletHooks>;
|
system: System<SilverBulletHooks>;
|
||||||
@ -196,9 +202,6 @@ export class ExpressServer {
|
|||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
this.space.updatePageList().catch(console.error);
|
this.space.updatePageList().catch(console.error);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
// Load plugs
|
|
||||||
this.reloadPlugs().catch(console.error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildMdExtensions() {
|
rebuildMdExtensions() {
|
||||||
@ -243,20 +246,78 @@ export class ExpressServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async reloadPlugs() {
|
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();
|
await this.space.updatePageList();
|
||||||
|
|
||||||
let allPlugs = await this.space.listPlugs();
|
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) {
|
if (allPlugs.length === 0) {
|
||||||
await this.bootstrapBuiltinPlugs();
|
await this.bootstrapBuiltinPlugs();
|
||||||
allPlugs = await this.space.listPlugs();
|
allPlugs = await this.space.listPlugs();
|
||||||
}
|
}
|
||||||
await this.system.unloadAll();
|
await this.system.unloadAll();
|
||||||
console.log("Loading plugs");
|
|
||||||
console.log(allPlugs);
|
console.log("Loading plugs", allPlugs);
|
||||||
for (let plugName of allPlugs) {
|
for (let plugName of allPlugs) {
|
||||||
let { data } = await this.space.readAttachment(plugName, "string");
|
let { data } = await this.space.readAttachment(plugName, "string");
|
||||||
await this.system.load(JSON.parse(data as string), createSandbox);
|
await this.system.load(JSON.parse(data as string), createSandbox);
|
||||||
}
|
}
|
||||||
this.rebuildMdExtensions();
|
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() {
|
async start() {
|
||||||
@ -278,6 +339,9 @@ export class ExpressServer {
|
|||||||
await ensureFTSTable(this.db, "fts");
|
await ensureFTSTable(this.db, "fts");
|
||||||
await this.ensureAndLoadSettings();
|
await this.ensureAndLoadSettings();
|
||||||
|
|
||||||
|
// Load plugs
|
||||||
|
this.reloadPlugs().catch(console.error);
|
||||||
|
|
||||||
// Serve static files (javascript, css, html)
|
// Serve static files (javascript, css, html)
|
||||||
this.app.use("/", express.static(this.distDir));
|
this.app.use("/", express.static(this.distDir));
|
||||||
|
|
||||||
|
@ -18,8 +18,5 @@ export function systemSyscalls(expressServer: ExpressServer): SysCallMapping {
|
|||||||
"system.reloadPlugs": async () => {
|
"system.reloadPlugs": async () => {
|
||||||
return expressServer.reloadPlugs();
|
return expressServer.reloadPlugs();
|
||||||
},
|
},
|
||||||
"system.getVersion": async () => {
|
|
||||||
return version;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -224,13 +224,10 @@ export class Editor {
|
|||||||
// console.log("Navigating to anchor", pos);
|
// console.log("Navigating to anchor", pos);
|
||||||
|
|
||||||
// We're going to look up the anchor through a direct page store query...
|
// 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.localSyscall("core", "index.get", [
|
||||||
let posLookup = await this.system.syscallWithContext(
|
pageName,
|
||||||
// Mock the "core" plug
|
`a:${pageName}:@${pos}`,
|
||||||
{ plug: { name: "core" } as any },
|
]);
|
||||||
"index.get",
|
|
||||||
[pageName, `a:${pageName}:@${pos}`]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!posLookup) {
|
if (!posLookup) {
|
||||||
return this.flashNotification(
|
return this.flashNotification(
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { SysCallMapping } from "@plugos/plugos/system";
|
import { SysCallMapping } from "@plugos/plugos/system";
|
||||||
import type { Editor } from "../editor";
|
import type { Editor } from "../editor";
|
||||||
import { CommandDef } from "../hooks/command";
|
import { CommandDef } from "../hooks/command";
|
||||||
import { version } from "../package.json";
|
|
||||||
|
|
||||||
export function systemSyscalls(editor: Editor): SysCallMapping {
|
export function systemSyscalls(editor: Editor): SysCallMapping {
|
||||||
return {
|
return {
|
||||||
@ -33,9 +32,6 @@ export function systemSyscalls(editor: Editor): SysCallMapping {
|
|||||||
}
|
}
|
||||||
return allCommands;
|
return allCommands;
|
||||||
},
|
},
|
||||||
"system.getVersion": async () => {
|
|
||||||
return version;
|
|
||||||
},
|
|
||||||
"system.reloadPlugs": async () => {
|
"system.reloadPlugs": async () => {
|
||||||
return editor.reloadPlugs();
|
return editor.reloadPlugs();
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user