| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- import { RPCExporter } from "rpclibrary";
- import { Git } from "upgiter"
- import { FolderStatus } from "upgiter/js/src/Types";
- import { Plugin } from "../Types/Plugin";
- import { FrontworkAdmin } from "../Admin/Admin";
-
- class PluginLoader {
- private runningPlugins: Plugin[] = []
- private pluginUpdaters:{[name in string]:Git.Updater} = {}
-
- constructor(private admin:FrontworkAdmin){}
-
- async selfUpdate(force:boolean = false){
- const updater = new Git.Updater({
- schema: 'https',
- localPath: './dist',
- remoteHost: 'www.versioncontrol.me',
- remotePath: 'frontwork-distribution',
- repoName: 'admin'
- })
-
- let status = await updater.getStatus()
- if(force || !status.remote || !status.remote.includes("fb-dist/admin") || !status.exists || status.empty || !status.currentTag){
- //logger.warn("Cloning fb-dist/admin into ./dist ..."+(force?" USING FORCE!":""))
- status = await updater.cloneRepo(force)
- const installer = eval("require")("./Installer").installAdmin
- installer(this.getPlugins())
- }
- return status
- }
-
- async installPlugin(name: string, force:boolean = false):Promise<FolderStatus>{
- //logger.warn("Cloning fb-dist/"+name+".git into ./plugins/"+name+" ..."+(force?" USING FORCE!":""))
- this.pluginUpdaters[name] = new Git.Updater({
- schema: 'https',
- localPath: './plugins/'+name,
- remoteHost: 'www.versioncontrol.me',
- remotePath: 'frontblock-distribution',
- repoName: name
- })
- const status = await this.pluginUpdaters[name].cloneRepo(force)
- return status
- }
-
- async startPlugin(name:string):Promise<boolean>{
- if(!this.pluginUpdaters[name]) return false
- const status = await this.pluginUpdaters[name].getStatus()
- if(!status.exists || status.empty || !status.tags || status.tags.length === 0){
- if(status.currentTag && !status.latestTag){
- //git glitches sometimes if you check immediately after clone
- //logger.warn("re-fetching tag for "+name+"...")
- return await this.startPlugin(name)
- }
- //logger.error("Bad repo status", name, status)
- return false
- }
-
- /* if(this.loadedPlugins[name]){
- logger.error("Plugin", name, "is already started")
- return false
- }
- */
-
- let evalstr = "../plugins/"+name+"/Plugin"
- const pluginClass = await eval('require')(evalstr)
- const pluginObj = new pluginClass.default(this.admin)
- try{
- if(pluginObj.start)
- await pluginObj.start()
- //this.pushNotification({message: "Started plugin "+pluginObj.name, severity: "Important", topic:"admin"})
- this.addPlugin(pluginObj)
- return true
- }catch(e){
- //logger.error(e)
- //this.pushNotification({message: "Start of plugin "+pluginObj.name+" failed because of "+String(e), severity: "Error", topic:"admin"})
- return false
- }
- }
-
- async updatePlugin(name:string):Promise<boolean>{
- if(!this.pluginUpdaters[name]) return false
- const status = await this.pluginUpdaters[name].getStatus()
- if(!status.exists || status.empty || !status.tags || status.tags.length === 0){
- //logger.error("Bad repo status", name, status)
- return false
- }
- if(status.currentTag == status.latestTag){
- //logger.warn(name, "already at latest tag")
- return false
- }
-
- /*
- if(this.loadedPlugins[name]){
- logger.error("Plugin", name, "is running. Stop it first")
- return false
- }
- */
-
- this.pluginUpdaters[name].checkoutTag(status.latestTag!)
- return true
- }
-
- async setPluginVersion(pluginName:string, tag:string):Promise<FolderStatus>{
- const status = await this.pluginUpdaters[pluginName].getStatus()
- if(!status.exists || !status.tags || status.tags.length === 0 || !status.tags.includes(tag)){
- //logger.error("Bad repo status", pluginName, status)
- return status
- }
-
- return await this.pluginUpdaters[pluginName].checkoutTag(tag)
- }
-
- async addPlugin(plugin: Plugin){
- this.runningPlugins.push(plugin)
- if(plugin.getTableDefinitions().length != 0)
- await this.admin.makeKnex()
- }
-
- removePlugin(plugin: Plugin){
- this.runningPlugins = this.runningPlugins.filter(p => p.name !== plugin.name)
- }
-
- getPlugins():Plugin[]{
- return [...this.runningPlugins]
- }
- }
-
-
- export type PluginLoaderIfc = {
- PluginLoader: {
- installPlugin: (name:string, force:boolean) => Promise<FolderStatus>
- startPlugin: (name:string) => Promise<boolean>
- updatePlugin: (name:string) => Promise<boolean>
- setPluginVersion: (name:string, tag:string) => Promise<FolderStatus>
- getLoadedPluginNames: () => Promise<String[]>
- selfUpdate: (force:boolean) => Promise<FolderStatus>
- }
- }
-
- export class RPCPluginLoader
- extends PluginLoader
- implements RPCExporter<PluginLoaderIfc, "PluginLoader">{
-
- name = "PluginLoader" as "PluginLoader";
-
- exportRPCs(){
- return [{
- name: "installPlugin" as "installPlugin",
- call: this.installPlugin,
- },{
- name: "startPlugin" as "startPlugin",
- call: this.startPlugin,
- },{
- name: "updatePlugin" as "updatePlugin",
- call: this.updatePlugin,
- },{
- name: "setPluginVersion" as "setPluginVersion",
- call: this.setPluginVersion,
- },{
- name: "getLoadedPluginNames" as "getLoadedPluginNames",
- call: async () => this.getPlugins().map(p => p.name),
- },{
- name: "selfUpdate" as "selfUpdate",
- call: this.selfUpdate,
- }]
- }
- }
|