flatmap works
This commit is contained in:
+95
-3
@@ -7,8 +7,7 @@ import { AdminBase } from 'frontblock-generic/Admin';
|
|||||||
import { FrontblockApi } from 'frontblock-generic/Api';
|
import { FrontblockApi } from 'frontblock-generic/Api';
|
||||||
import { Plugin } from 'frontblock-generic/Plugin';
|
import { Plugin } from 'frontblock-generic/Plugin';
|
||||||
import { socketioRPC } from 'frontblock-generic/RPC';
|
import { socketioRPC } from 'frontblock-generic/RPC';
|
||||||
import { GitUpdater } from './GitUpdater';
|
import { GitUpdater, RepoFolderStatus } from './GitUpdater';
|
||||||
import { UpdateManager } from './UpdateManger';
|
|
||||||
|
|
||||||
Logger.configure({
|
Logger.configure({
|
||||||
appenders:
|
appenders:
|
||||||
@@ -28,9 +27,10 @@ export type AdminConf = { httpPort: number}
|
|||||||
|
|
||||||
export class FrontblockAdmin extends AdminBase<AdminConf>{
|
export class FrontblockAdmin extends AdminBase<AdminConf>{
|
||||||
|
|
||||||
|
private pluginUpdaters:{[name in string]:GitUpdater} = {}
|
||||||
|
|
||||||
constructor(runningPlugins: Plugin[] = []){
|
constructor(runningPlugins: Plugin[] = []){
|
||||||
super(runningPlugins)
|
super(runningPlugins)
|
||||||
this.addPlugin(new UpdateManager(this))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultConfig(): { apiConf: FrontblockApiConf; } & AdminConf & { dbConf:Knex.Config; } {
|
getDefaultConfig(): { apiConf: FrontblockApiConf; } & AdminConf & { dbConf:Knex.Config; } {
|
||||||
@@ -66,6 +66,31 @@ export class FrontblockAdmin extends AdminBase<AdminConf>{
|
|||||||
return [
|
return [
|
||||||
...super.exportRPCs(),
|
...super.exportRPCs(),
|
||||||
{
|
{
|
||||||
|
name: 'installPlugin',
|
||||||
|
func: async (name:string, force = false) => {return await this.installPlugin(name, force)},
|
||||||
|
type: 'call',
|
||||||
|
visibility: 'private'
|
||||||
|
},{
|
||||||
|
name: 'startPlugin',
|
||||||
|
func: async (name:string) => {return await this.startPlugin(name)},
|
||||||
|
type: 'call',
|
||||||
|
visibility: 'private'
|
||||||
|
},{
|
||||||
|
name: 'updatePlugin',
|
||||||
|
func: async (name) => {return await this.updatePlugin(name)},
|
||||||
|
type: 'call',
|
||||||
|
visibility: 'private'
|
||||||
|
},{
|
||||||
|
name: 'setPluginVersion',
|
||||||
|
func: async (name, tag) => {return await this.setPluginVersion(name, tag)},
|
||||||
|
type: 'call',
|
||||||
|
visibility: 'private'
|
||||||
|
},{
|
||||||
|
name: 'getLoadedPluginNames',
|
||||||
|
func: async () => {return await this.getPlugins().map(p => p.name)},
|
||||||
|
type: 'call',
|
||||||
|
visibility: 'private'
|
||||||
|
},{
|
||||||
name: 'selfUpdate',
|
name: 'selfUpdate',
|
||||||
type:'call',
|
type:'call',
|
||||||
func: async (force: boolean) => {return await this.selfUpdate(force)},
|
func: async (force: boolean) => {return await this.selfUpdate(force)},
|
||||||
@@ -87,6 +112,73 @@ export class FrontblockAdmin extends AdminBase<AdminConf>{
|
|||||||
}
|
}
|
||||||
return status
|
return status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async installPlugin(name: string, force:boolean = false):Promise<RepoFolderStatus>{
|
||||||
|
logger.warn("Cloning fb-dist/"+name+".git into ./plugins/"+name+" ..."+(force?" USING FORCE!":""))
|
||||||
|
this.pluginUpdaters[name] = new GitUpdater("./plugins/"+name)
|
||||||
|
const status = await this.pluginUpdaters[name].cloneRepo("https://gitea.frontblock.me/fb-dist/"+name.toLowerCase()+".git", 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 str = "../plugins/"+name+"/Plugin"
|
||||||
|
const pluginClass = await eval('require')(str)
|
||||||
|
const pluginObj = new pluginClass.default()
|
||||||
|
await pluginObj.start()
|
||||||
|
this.addPlugin(pluginObj)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
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<RepoFolderStatus>{
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process.on( 'SIGINT', function() {
|
process.on( 'SIGINT', function() {
|
||||||
|
|||||||
@@ -89,20 +89,20 @@ export class FrontblockConfigLib{
|
|||||||
}
|
}
|
||||||
|
|
||||||
window['fb'] = new FrontblockConfigLib()
|
window['fb'] = new FrontblockConfigLib()
|
||||||
declare const fb:{UpdateManager:any}
|
declare const fb:{Admin:any}
|
||||||
window['setup'] = async() => {
|
window['setup'] = async() => {
|
||||||
const i = await Promise.all([
|
const i = await Promise.all([
|
||||||
fb.UpdateManager.installPlugin("ApiClient"),
|
fb.Admin.installPlugin("ApiClient"),
|
||||||
fb.UpdateManager.installPlugin("HtmlSupplier"),
|
fb.Admin.installPlugin("HtmlSupplier"),
|
||||||
fb.UpdateManager.installPlugin("PaymentManager"),
|
fb.Admin.installPlugin("PaymentManager"),
|
||||||
fb.UpdateManager.installPlugin("Wallet"),
|
fb.Admin.installPlugin("Wallet"),
|
||||||
])
|
])
|
||||||
console.log(i)
|
console.log(i)
|
||||||
const s = await Promise.all([
|
const s = await Promise.all([
|
||||||
fb.UpdateManager.startPlugin("ApiClient"),
|
fb.Admin.startPlugin("ApiClient"),
|
||||||
fb.UpdateManager.startPlugin("HtmlSupplier"),
|
fb.Admin.startPlugin("HtmlSupplier"),
|
||||||
fb.UpdateManager.startPlugin("PaymentManager"),
|
fb.Admin.startPlugin("PaymentManager"),
|
||||||
fb.UpdateManager.startPlugin("Wallet"),
|
fb.Admin.startPlugin("Wallet"),
|
||||||
])
|
])
|
||||||
if(s.reduce((p,c) => p && c), true)
|
if(s.reduce((p,c) => p && c), true)
|
||||||
location.reload();
|
location.reload();
|
||||||
|
|||||||
@@ -1,143 +0,0 @@
|
|||||||
import { Plugin } from "frontblock-generic/Plugin";
|
|
||||||
import { socketioRPC } from "frontblock-generic/RPC";
|
|
||||||
import { GitUpdater, RepoFolderStatus } from "./GitUpdater";
|
|
||||||
import { FrontblockCherryPicker } from "git-cherrypicker";
|
|
||||||
import * as Logger from 'log4js'
|
|
||||||
import { FrontblockAdmin } from "./Admin";
|
|
||||||
import { TableDefiniton } from "frontblock-generic/Admin";
|
|
||||||
|
|
||||||
Logger.configure({
|
|
||||||
appenders:
|
|
||||||
{
|
|
||||||
"admin/updatemanager": { type: 'stdout' },
|
|
||||||
//app: { type: 'file', filename: 'application.log' }
|
|
||||||
},
|
|
||||||
categories:
|
|
||||||
{
|
|
||||||
default: { appenders: [ 'admin/updatemanager' ], level: 'debug' }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const logger = Logger.getLogger("admin/updatemanager")
|
|
||||||
|
|
||||||
export class UpdateManager extends Plugin{
|
|
||||||
|
|
||||||
private loadedPlugins:{[name in string]:Plugin} = {}
|
|
||||||
private dashboardUpdater:GitUpdater
|
|
||||||
private adminUpdater:GitUpdater
|
|
||||||
private pluginUpdaters:{[name in string]:GitUpdater} = {}
|
|
||||||
|
|
||||||
constructor(admin:FrontblockAdmin){
|
|
||||||
super(admin, "UpdateManager")
|
|
||||||
}
|
|
||||||
|
|
||||||
getDefaultConfig(): {} {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
exportRPCs(): socketioRPC[] {
|
|
||||||
return [{
|
|
||||||
name: 'installPlugin',
|
|
||||||
func: async (name:string, force = false) => {return await this.installPlugin(name, force)},
|
|
||||||
type: 'call',
|
|
||||||
visibility: 'private'
|
|
||||||
},{
|
|
||||||
name: 'startPlugin',
|
|
||||||
func: async (name:string) => {return await this.startPlugin(name)},
|
|
||||||
type: 'call',
|
|
||||||
visibility: 'private'
|
|
||||||
},{
|
|
||||||
name: 'updatePlugin',
|
|
||||||
func: async (name) => {return await this.updatePlugin(name)},
|
|
||||||
type: 'call',
|
|
||||||
visibility: 'private'
|
|
||||||
},{
|
|
||||||
name: 'setPluginVersion',
|
|
||||||
func: async (name, tag) => {return await this.setPluginVersion(name, tag)},
|
|
||||||
type: 'call',
|
|
||||||
visibility: 'private'
|
|
||||||
},{
|
|
||||||
name: 'getLoadedPluginNames',
|
|
||||||
func: async () => {return await this.getLoadedPluginNames()},
|
|
||||||
type: 'call',
|
|
||||||
visibility: 'private'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
getTableDefinitions(): TableDefiniton[] {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
async installPlugin(name: string, force:boolean = false):Promise<RepoFolderStatus>{
|
|
||||||
logger.warn("Cloning fb-dist/"+name+".git into ./plugins/"+name+" ..."+(force?" USING FORCE!":""))
|
|
||||||
this.pluginUpdaters[name] = new GitUpdater("./plugins/"+name)
|
|
||||||
const status = await this.pluginUpdaters[name].cloneRepo("https://gitea.frontblock.me/fb-dist/"+name.toLowerCase()+".git", 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 str = "../plugins/"+name+"/Plugin"
|
|
||||||
const pluginClass = await eval('require')(str)
|
|
||||||
const pluginObj = new pluginClass.default()
|
|
||||||
await pluginObj.start()
|
|
||||||
this.admin.addPlugin(pluginObj)
|
|
||||||
this.loadedPlugins[name] = pluginObj
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
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<RepoFolderStatus>{
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
getLoadedPlugins():Plugin<any>[]{
|
|
||||||
return Object.values(this.loadedPlugins)
|
|
||||||
}
|
|
||||||
|
|
||||||
getLoadedPluginNames():string[]{
|
|
||||||
return Object.keys(this.loadedPlugins)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -52,7 +52,7 @@ import { FrontendPlugin, SidebarEntries, SidebarEntry } from "frontblock-generic
|
|||||||
import { environment } from "../../environments/environment"
|
import { environment } from "../../environments/environment"
|
||||||
|
|
||||||
const fb = environment.production ? window["fb"] : {
|
const fb = environment.production ? window["fb"] : {
|
||||||
UpdateManager: {
|
Admin: {
|
||||||
getLoadedPluginNames: () => ["ApiClient", "Wallet"]
|
getLoadedPluginNames: () => ["ApiClient", "Wallet"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,10 +78,10 @@ export class DynamicLoaderComponent implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async loadWidgets() {
|
private async loadWidgets() {
|
||||||
while (!fb.UpdateManager) {
|
while (!fb.Admin) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||||
}
|
}
|
||||||
const pluginNames = await fb.UpdateManager.getLoadedPluginNames()
|
const pluginNames = await fb.Admin.getLoadedPluginNames()
|
||||||
pluginNames.forEach(element => this.installWidget(element));
|
pluginNames.forEach(element => this.installWidget(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user