maj setup

This commit is contained in:
2023-05-31 15:19:21 +02:00
parent 85862577b2
commit 908daaa8d3
22 changed files with 810 additions and 332 deletions

View File

@@ -3,12 +3,12 @@ const fs = require("fs-extra");
const glob = require("glob");
const jwt = require("jwt-simple");
const axios = require("axios");
const path=require('path');
const conf=require(`${process.env.dirtown}/conf.json`);
const Odmdb = require('./Odmdb.js');
const path = require("path");
const conf = require(`${process.env.dirtown}/conf.json`);
const Odmdb = require("./Odmdb.js");
// lowercase 1st letter is normal
const towns = require('./Towns.js');
const pagans = require('./Pagans.js');
const towns = require("./Towns.js");
const pagans = require("./Pagans.js");
/*
Blockchain manager
* Manage network directory of nations and towns
@@ -23,68 +23,96 @@ Nations.init = () => {
console.group("init Nations");
};
Nations.updateChains = async (newtown) =>{
Nations.chaintown = (nationId, townId) => {
/**
* @newtown {object} optional to request a registration in the nationchain network
* if newtown exist then it send a request to update itself else it just refresh from existing town.
* Check public nationchains are up to date from the existing list of towns
* Each object to sync have a /idx/conf.json with key lastupdate = timestamp last update
* tribes is not synchonized and contain private information
* A town is a network node of the nationchains and allow to synchronize new
* if not already exist Add a requested town into conf.towns.push({ "townId": "wall", "nationId": "ants", "dns": "wall-ants.ndda.fr" })
*/
const res= {status:400};
const ref2update={}
glob.sync(`${__dirapi}nationchains/**/idx/conf.json`).forEach(f=>{
const ref=fs.readJsonSync(f)
ref2update[path.basename(ref.schema,'.json')]=ref.lastupdate;
})
console.log(ref2update)
// Get list of town to check n of them have fresh update
const knowntowns =fs.readJsonSync(`${__dirapi}nationchains/towns/idx/towns_townId_all.json`);
let promiselistblock=[]
let towidlist=[]
Object.keys(knowntowns).forEach(townid=>{
// identify the town with the highest block to update town
promiselistblock.push(axios.get(`https://${knowntowns[townid].url}/blocks/idx/conf.json`));
townidlistblock.push(townid)
});
let selectedtown=""
let blocnum=0
await Promise.all(promiselistblock)
.then(rep=>{
for (let pos=0;pos<townidlist.length;pos++){
if (rep[pos].blocnum > blocnum) {
selectedtown=townidlist[pos]
blocnum=rep[pos].blocnum
};
Nations.updateobjectsfromfreshesttown = (dnstownlist, objectidx) => {
/**
* Get lasttime update per apxtrib object then choose the latest source and update local town
* if an item exist localy and does not from the town requested
* @Param {array} dnstownlist list of dns to get latest data
* @Param {object} objectidx objectnme:idxfile {agans:"alias_all.json",...}
* @return create/update nationchains/pagans town nation
*/
const localversion = {};
const objlist = Object.keys(objectidx);
objlist.forEach((o) => {
let objconf = {
name: o,
schema: `nationchains/schema/${o}.jsons`,
lastupdate: -1,
};
if (fs.existsSync(`${conf.dirapi}/nationchains/${o}/conf.json`)) {
objconf = fs.readJsonSync(`${conf.dirapi}/nationchains/${o}/conf.json`);
} else {
fs.outputJsonSync(`${conf.dirapi}/nationchains/${o}/conf.json`, objconf);
}
localversion[o] = [conf.dns[0], objconf.lastupdate];
});
//console.log(localversion);
for (let t = 0; t < dnstownlist.length; t++) {
let promiseconf = [];
let objecttotest = [];
objlist.forEach((o) => {
//console.log(`https://${dnstownlist[t].dns}/nationchains/${o}/conf.json`);
objecttotest.push(o);
promiseconf.push(
axios.get(`https://${dnstownlist[t].dns}/nationchains/${o}/conf.json`)
);
});
Promise.all(promiseconf)
.then((reps) => {
let promiseidx = [];
let objecttoupdate = [];
let objlastupdate = [];
for (let i = 0; i < objecttotest.length; i++) {
if (
parseInt(reps[i].data.lastupdate) >
parseInt(localversion[reps[i].data.name][1])
) {
// add promise to get data
/*console.log(
`https://${dnstownlist[t].dns}/nationchains/${
reps[i].data.name
}/idx/${objectidx[reps[i].data.name]}`
);*/
objecttoupdate.push(objecttotest[i]);
objlastupdate.push(reps[i].data.lastupdate);
promiseidx.push(
axios.get(
`https://${dnstownlist[t].dns}/nationchains/${
reps[i].data.name
}/idx/${objectidx[reps[i].data.name]}`
)
);
}
}
Promise.all(promiseidx)
.then((rets) => {
for (let j = 0; j < objecttoupdate.length; j++) {
Odmdb.updatefromidxall(
objecttoupdate[j],
objectidx[objecttoupdate[j]],
rets[j].data,
objlastupdate[j]
);
}
}
})
.catch((err) => {
console.log("ERR get idx data");
console.log(err);
});
})
.catch(err=>{
console.log(err)
})
let promiselistref=[]
Object.keys(ref2update).forEach(ob=>{
promiselistref.push(axios.get(`${knowntowns[selectedtown].url}/${obj}/idx/conf.json`));
})
await Promise.all(promiselistref)
.then(rep=>{
for (let pos=0;pos<townidlist.length;pos++){
//si axios lastupdate > local lastupate => recupe _all et regenere tous les objets par ecrasement
}
})
.catch(err=>{
console.log(err)
})
return res
}
Nations.update=(nationsource)=>{
/**
* Update object nation with last update
*/
}
Nations.synchronize = () => {
.catch((err) => {
console.log("ERR get conf lastupdate");
console.log(err);
});
}
};
Nations.synchronizeold = () => {
/*
Run process to communicate with a list of towns to update network and transaction
*/
@@ -189,8 +217,8 @@ Nations.create = (conf) => {
@return
*/
const res = {};
if (conf.object=="towns"){
Odmdb.create("nationchains/socialworld/objects","towns",conf);
if (conf.object == "towns") {
Odmdb.create("nationchains/socialworld/objects", "towns", conf);
}
const nations = fs.readJsonSync(
"./nationchains/nations/idx/nationId_all.json"
@@ -200,7 +228,7 @@ Nations.create = (conf) => {
res.info = `your nationId ${conf.nationId} does not exist you have to choose an existing one`;
return res;
}
const towns = fs.readJsonSync( "./nationchains/towns/idx/townId_all.json")
const towns = fs.readJsonSync("./nationchains/towns/idx/townId_all.json");
if (towns[conf.nationId].includes(conf.townId)) {
res.status = 409;
res.info = `This conf.townId already exist you have to find a unique town name`;
@@ -210,18 +238,20 @@ Nations.create = (conf) => {
uuid: conf.townId,
nationid: conf.nationId,
url: `${conf.townId}.${conf.nationId}.${conf.dns}`,
status: (conf.dns=="unchain")? "unchain" : "tochain",
status: conf.dns == "unchain" ? "unchain" : "tochain",
};
const metatown=fs.readJsonSync('./nationchains/socialworld/metaobject/towns.json');
Odmdb.add(objectpath, towns, metatown,towndata)
const metatown = fs.readJsonSync(
"./nationchains/socialworld/metaobject/towns.json"
);
Odmdb.add(objectpath, towns, metatown, towndata);
fs.outputJsonSync(
`./nationchains/socialworld/objects/towns/${townId}.json`,
towndata
);
res.status=200
res.info=`${townId} create for ${nationId} nation`;
return res
res.status = 200;
res.info = `${townId} create for ${nationId} nation`;
return res;
};
module.exports = Nations;

View File

@@ -1,8 +1,8 @@
const glob = require("glob");
const path = require("path");
const fs = require("fs-extra");
const axios = require('axios');
const conf=require(`${process.env.dirtown}/conf.json`)
const dayjs = require("dayjs");
const conf = require(`${process.env.dirtown}/conf.json`);
const Checkjson = require(`./Checkjson.js`);
/* This manage Objects for indexing and check and act to CRUD
@@ -20,11 +20,12 @@ Input: metaobject => data mapper of Key: Value
objname + action index => update /searcindex of objects concern
*/
Odmdb.setObject=(schemaPath, objectPath, objectName, schema, lgjson, lg)=>{
/**
*
Odmdb.setObject = (schemaPath, objectPath, objectName, schema, lgjson, lg) => {
/**
*
* @schemapath {string} path to create or replace a schema ${schemaPath}/schema/
* @objectPath {string} path where object are store
* @objectPath {string} path where object are store
* @objectName {string} name of the object
* @schema {object} the json schema for this object
* @lgjson {object} the json file for a specific language
@@ -37,26 +38,51 @@ Odmdb.setObject=(schemaPath, objectPath, objectName, schema, lgjson, lg)=>{
* objectPath/objectName/idx/confjson ={"schema":"relativpathfile or http"}
* /uniqueid.json defining schema
*
*/
if (!fs.existsSync(schemaPath)){
return {status:404, ref:"Odmdb", info:"pathnamedoesnotexist", moreinfo:{fullpath:schemaPath}}
*/
if (!fs.existsSync(schemaPath)) {
return {
status: 404,
ref: "Odmdb",
info: "pathnamedoesnotexist",
moreinfo: { fullpath: schemaPath },
};
}
if (!fs.existsSync(objectPath)){
return {status:404, ref:"Odmdb", info:"pathnamedoesnotexist",moreinfo:{fullpath:objectPath}}
if (!fs.existsSync(objectPath)) {
return {
status: 404,
ref: "Odmdb",
info: "pathnamedoesnotexist",
moreinfo: { fullpath: objectPath },
};
}
// store schema file if not empty undefined or {}
if (schema && !(Object.keys(schema).length === 0 && schema.constructor === Object)){
fs.outputJSONSync(`${schemaPath}/schema/${objectName}.json`,schema, {spaces:2})
if (
schema &&
!(Object.keys(schema).length === 0 && schema.constructor === Object)
) {
fs.outputJSONSync(`${schemaPath}/schema/${objectName}.json`, schema, {
spaces: 2,
});
}
if (lgjson && lg && !(Object.keys(lgjson).length === 0 && lgjson.constructor === Object)){
fs.outputJSONSync(`${schemaPath}/lg/${objectName}_${lg}.json`,lgjson, {spaces:2})
if (
lgjson &&
lg &&
!(Object.keys(lgjson).length === 0 && lgjson.constructor === Object)
) {
fs.outputJSONSync(`${schemaPath}/lg/${objectName}_${lg}.json`, lgjson, {
spaces: 2,
});
}
//create environnement object with the new schema config
if (!fs.existsSync(`${objectPath}/${objectName}`)){
fs.outputJsonSync(`${objectPath}/${objectName}/idx/confjson`,{schema:`${schemaPath}/schema/${objectName}.json`},{spaces:2})
if (!fs.existsSync(`${objectPath}/${objectName}`)) {
fs.outputJsonSync(
`${objectPath}/${objectName}/idx/confjson`,
{ schema: `${schemaPath}/schema/${objectName}.json` },
{ spaces: 2 }
);
}
return {status:200}
}
return { status: 200 };
};
Odmdb.schema = (schemaPath, objectName, withschemacheck) => {
// Return schema if exist and objectpath contain objectName { status:200;data:schema}
@@ -76,7 +102,7 @@ Odmdb.schema = (schemaPath, objectName, withschemacheck) => {
const schema = fs.readJsonSync(`${schemaPath}/schema/${objectName}.json`);
// check schema apx validity specificities primary unique ans searchindex
if (withschemacheck) {
if (!schema.apxprimarykey) {
if (!schema.apxprimarykey) {
// code 422: unprocessable Content
return {
status: 422,
@@ -137,12 +163,14 @@ Odmdb.Checkjson = (objectPath, objectName, data, withschemacheck) => {
*/
const res = { status: 200 };
//get schema link of object
const schemaPath = fs.readJsonSync(`${objectPath}/${objectName}/idx/confjson`)['schema']
if (schemaPath.substring(0,4)=="http"){
// lance requete http pour recuperer le schema
}else{
schema=="!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
}
const schemaPath = fs.readJsonSync(
`${objectPath}/${objectName}/idx/confjson`
)["schema"];
if (schemaPath.substring(0, 4) == "http") {
// lance requete http pour recuperer le schema
} else {
schema == "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
}
// check schema validity
const schema = Odmdb.schema(objectPath, objectName, withschemacheck);
if (schema.status != 200) return schema;
@@ -260,4 +288,74 @@ console.log(
{ nationId: "123", status: "unchain" }
)
);*/
Odmdb.updatefromidxall = (objectname, idxname, data, lastupdate) => {
/**
* Update all itm of objectname from index idx/idxname with data
* if itm exist in local and not in data then /ojectname/conf.json.lastupdate = now
* not then /ojectname/conf.json.lastupdate = lastupdate
* this way mean next time server A want to refresh from B its lastupdate < than on A
*/
let conflastupdate = 0;
let localidx = {};
if (
fs.existsSync(`${conf.dirapi}/nationchains/${objectname}/idx/${idxname}`)
) {
localidx = fs.readJsonSync(
`${conf.dirapi}/nationchains/${objectname}/idx/${idxname}`
);
}
Object.keys(data).forEach((id) => {
if (localidx[id]) {
if (
localidx[id].dt_update &&
data[id].dt_update &&
localidx[id].dt_update > data[id].dt_update
) {
// means local information is fresher than the one in data for replacement
conflastupdate = dayjs();
} else {
// replace itm with data
localidx[id] = data[id];
fs.outputJsonSync(
`${conf.dirapi}/nationchains/${objectname}/itm/${id}.json`,
data[id]
);
}
} else {
// add itm
localidx[id] = data[id];
fs.outputJsonSync(
`${conf.dirapi}/nationchains/${objectname}/itm/${id}.json`,
data[id]
);
}
});
//check if it miss id in fresher update means conf.lastupdate will be now to indicate
Object.keys(localidx).forEach((id) => {
if (!data[id]) {
conflastupdate = dayjs();
}
});
// update the object files
if (conflastupdate == 0) conflastupdate = lastupdate;
fs.outputJSONSync(
`${conf.dirapi}/nationchains/${objectname}/idx/${idxname}`,
localidx
);
const objconf = fs.readJsonSync(
`${conf.dirapi}/nationchains/${objectname}/conf.json`
);
objconf.lastupdate = conflastupdate;
fs.outputJsonSync(
`${conf.dirapi}/nationchains/${objectname}/conf.json`,
objconf
);
return {
status: 200,
ref: "Odmdb.js",
info: "Successfullupdate",
data: { objectname, idxname, lastupdate },
};
};
module.exports = Odmdb;

View File

@@ -9,7 +9,7 @@ const openpgp = require("openpgp");
conf = require("../../nationchains/tribes/conf.json");
}*/
const conf = require(`${process.env.dirtown}/conf.json`);
console.log(conf);
/**
* Pagan Management numeric Identity and Person (Person = Pagan Id + tribe)
*
@@ -58,7 +58,11 @@ Pagans.personupdate = (alias, tribe, persondata) => {
dt_create: dayjs(),
accessrights: { profil: "user" },
};
if (fs.existsSync(`${process.env.dirtown}/tribes/${tribe}/person/itm/${alias}.json`)) {
if (
fs.existsSync(
`${process.env.dirtown}/tribes/${tribe}/person/itm/${alias}.json`
)
) {
person = fs.readJsonSync(
`${process.env.dirtown}/tribes/${tribe}/person/itm/${alias}.json`
);

View File

@@ -1,12 +1,10 @@
const { argv } = require('process');
const { argv } = require("process");
const fs = require("fs-extra");
const path = require("path");
const dnsSync = require("dns-sync");
const mustache = require("mustache");
const readlineSync = require("readline-sync");
const Wwws = require("../models/Wwws.js");
const Nations = require("../models/Nations.js");
/**
* This Setup is run at the first installation
* This is not an exportable module
@@ -20,33 +18,70 @@ const Setup = {};
Setup.check = (param) => {
//run a nationchains sync nd check town does not already exist
["nationId","townId","url"].forEach(k=>{
if (!param[k]){
console.log(`Please provide a ${k} in your param`)
["nationId", "townId", "dns", "chain"].forEach((k) => {
if (!param[k]) {
console.log(`Please provide a ${k} in your param`);
process.exit();
}
})
const initconf = fs.readJsonSync('./adminapi/www/adminapx/tpldata/initconf.json')
let nationupdated=false;
for (let t=0; t<initconf.towns;t++){
const synchro = Nations.synchronize(initconf.towns[t].url)
if (synchro.status==200){
nationupdated=true;
break;}
});
const localconf = {
nationId: param.nationId,
townId: param.townId,
url:param.dns,
comment: "Generate by setup.js with minimum of information",
};
if (fs.existsSync(`../../adminapi/www/adminapx/conf/setup_xx.json`)) {
const setupxx=readJsonSYnc(`../../adminapi/www/adminapx/conf/setup_xx.json`)
if (setupxx.nationId==param.nationId && setupxx.townId=param.townId) {
// This is a re-install
}else{
console.log(
"A conf file exist in adminapi/www/adminapx/conf/setup_xx.json remove it an run again yarn setup ..."
);
process.exit();
}
}
if (!nationupdated){
Console.log('Please check your internet access other towns cannot be reach to synchronize your town')
fs.outputJsonSync(
`../../adminapi/www/adminapx/conf/setup_xx.json`,
localconf
);
const initconf = fs.readJsonSync(
"./adminapi/www/adminapx/tpldata/initconf.json"
);
let nationupdated = false;
const Wwws = require("../models/Wwws.js");
const Nations = require("../models/Nations.js");
for (let t = 0; t < initconf.towns; t++) {
const synchro = Nations.synchronize(initconf.towns[t].dns);
if (synchro.status == 200) {
nationupdated = true;
break;
}
}
if (!nationupdated) {
Console.log(
"Please check your internet access other towns cannot be reach to synchronize your town"
);
process.exit();
}
// check nationId exist and townId not
if (!Object.keys(fs.readJsonSync('../../nationchains/nations/idx/nationId_all.json')).includes(param.nationId) {
console.log(`Sorry your nationId: ${param.nationId} does not exist`);
process.exit();
}
if (Object.keys(fs.readJsonSync('../../nationchains/towns/idx/townId_all.json')).includes(param.townId) {
console.log(`Sorry your townId: ${param.townId} already exist, please choose another one`);
const idxnationId = fs.readJsonSync(
`../../nationchains/nations/idx/nationId_all.json`
);
if (!Object.keys(idxnationId).includes(param.nationId)) {
console.log(`Sorry your nationId: ${param.nationId} does not exist`);
process.exit();
}
}
const idxtownId = fs.readJsonSync(
"../../nationchains/towns/idx/townId_all.json"
);
if (Object.keys(idxtownId).includes(param.townId)) {
console.log(
`Sorry your townId: ${param.townId} already exist, please choose another one`
);
process.exit();
}
if ("testinternet" != "testinternet") {
console.log(
"\x1b[31m Check your internet access, to setup this town we need to update the Nations. It seems we cannot do it"
@@ -76,20 +111,20 @@ Setup.init = async (param) => {
* Then to send new version we fix a master production
*
*/
const initconf = fs.readJsonSync('./adminapi/www/adminapx/tpldata/initconf.json')
const initconf = fs.readJsonSync(
"./adminapi/www/adminapx/tpldata/initconf.json"
);
initconf.sudoerUser = process.env.USER;
initconf.dirapi = path.resolve(`${__dirname}/../../`);
initconf.dirtown = path.resolve(`${__dirname}/../../../${param.townId}-${param.nationId}/`)
initconf.dirtown = path.resolve(
`${__dirname}/../../../${param.townId}-${param.nationId}/`
);
// To allow to serve the nation website until the end
initconf.nginx.include.push(
`${initconf.dirapi}/adminapi/www/nginx_*.conf`
);
initconf.nginx.include.push(`${initconf.dirapi}/adminapi/www/nginx_*.conf`);
// To allow to serve tribes web site
initconf.nginx.include.push(
`${initconf.dirtown}/tribes/*/www/nginx_*.conf`
);
initconf.dns.push(param.url)
initconf.nginx.include.push(`${initconf.dirtown}/tribes/*/www/nginx_*.conf`);
initconf.dns.push(param.dns);
initconf.nginx.logs = `${dirtown}/logs/nginx/adminapx`;
initconf.nginx.website = "adminapx";
initconf.nginx.fswww = `${dirapi}/adminapi/www`;
@@ -121,32 +156,38 @@ Setup.init = async (param) => {
);
if (!fs.existsSync(initconf.nginx.logs)) fs.mkdirSync(initconf.nginx.logs);
const { exec } = require("child_process");
exec(.restart, (error, stdout, stderr) => {
exec(initconf.restart, (error, stdout, stderr) => {
if (error) {
console.log("\x1b[42m", error, stdout, stderr, "x1b[0m");
//@todo supprimer la derniere config et relancer
console.log("\x1b[42m", error, stdout, stderr, "x1b[0m");
//@todo supprimer la derniere config et relancer
} else {
console.log(
`\x1b[42m###########################################################################################\x1b[0m\n\x1b[42mWellcome into apxtrib, you can now 'yarn dev' for dev or 'yarn startpm2' for prod or \n'yarn unittest' for testing purpose. Access to your town here \x1b[0m\x1b[32mhttp://${param.url}\x1b[0m \x1b[42m \nto finish your town setup. Don't forget to set your localhost /etc/hosts by adding 127.0.0.1 adminapx or {LAN IP} adminapx . Check README's project to learn more. \x1b[0m\n\x1b[42m###########################################################################################\x1b[0m`
);
console.log(
`\x1b[42m###########################################################################################\x1b[0m\n\x1b[42mWellcome into apxtrib, you can now 'yarn dev' for dev or 'yarn startpm2' for prod or \n'yarn unittest' for testing purpose. Access to your town here \x1b[0m\x1b[32mhttp://${param.dns}\x1b[0m \x1b[42m \nto finish your town setup. Don't forget to set your localhost /etc/hosts by adding 127.0.0.1 adminapx or {LAN IP} adminapx . Check README's project to learn more. \x1b[0m\n\x1b[42m###########################################################################################\x1b[0m`
);
}
});
};
if (argv.length!=5) {
console.log("Check you parameter you need to type yarn setup nationId:ants townid:mytown url:mytown-ants ")
process.exit()
if (argv.length != 6) {
console.log(
"Check you parameter you need to type yarn setup nationId:ants townid:mytown dns:mytown-ants "
);
process.exit();
}
const param={};
argv.slice(2).forEach(arg=>{
const kv=arg.split(':')
if (kv.length==2){
param[kv[0]]=kv[1]
}else{
console.log('Check your args that have to be yarn main key1:val1 keyn:valn');
process.exit(1);
}
})
if (Setup.check(param)) Setup.init(param);
const param = {};
argv.slice(2).forEach((arg) => {
const kv = arg.split(":");
if (kv.length == 2) {
param[kv[0]] = kv[1];
} else {
console.log(
"Check your args that have to be yarn main key1:val1 keyn:valn"
);
process.exit(1);
}
});
console.log(param);
//if (Setup.check(param)) Setup.init(param);
// After testing remove all stuff after this line
@@ -251,7 +292,7 @@ Setup.initold = async () => {
/* townconf.town = {
townId: townconf.townId,
nationId: townconf.nationId,
url: `http://${townconf.dns[0]}`,
dns: `http://${townconf.dns[0]}`,
IP: townconf.IP,
mayorid: townconf.mayorId,
status: "unchain",
@@ -469,4 +510,3 @@ Setup.druidid = (townSetup) => {
console.log("Issue ", createclient);
}
};