From 7b859e9d3b6cd05639c1c9fc8801c7d212875f08 Mon Sep 17 00:00:00 2001 From: michael shanks Date: Mon, 1 Jul 2019 22:49:13 +0100 Subject: [PATCH] can deploy versions of apps --- .../appPackages/master/appDefinition.json | 438 +++++++++++++++++- packages/server/appPackages/master/main.js | 22 +- .../appPackages/testApp/dist/package.tar.gz | Bin 1500 -> 1500 bytes .../server/initialise/createInstanceDb.js | 8 +- .../testApp/3-dYHF49T8Oyo/access_levels.json | 1 + .../testApp/3-dYHF49T8Oyo/appDefinition.json | 1 + packages/server/tests/createNewApp.js | 7 +- packages/server/tests/testApp.js | 4 +- packages/server/utilities/runtimePackages.js | 9 +- packages/server/utilities/targzAppPackage.js | 15 +- 10 files changed, 478 insertions(+), 27 deletions(-) create mode 100644 packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/access_levels.json create mode 100644 packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/appDefinition.json diff --git a/packages/server/appPackages/master/appDefinition.json b/packages/server/appPackages/master/appDefinition.json index 5cb778ac4..29f29fa89 100644 --- a/packages/server/appPackages/master/appDefinition.json +++ b/packages/server/appPackages/master/appDefinition.json @@ -1 +1,437 @@ -{"hierarchy":{"name":"root","type":"root","children":[{"name":"application","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":500,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"domain","type":"string","typeOptions":{"maxLength":500,"values":null,"allowDeclaredValuesOnly":false},"label":"domain","getInitialValue":"default","getUndefinedValue":"default"},{"name":"application_resolve_strategy","type":"string","typeOptions":{"maxLength":100,"values":["domain","path"],"allowDeclaredValuesOnly":true},"label":"Resolve Application By","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"user","type":"record","fields":[{"name":"unique_name","type":"string","typeOptions":{"maxLength":200,"values":null,"allowDeclaredValuesOnly":false},"label":"Name (unique)","getInitialValue":"default","getUndefinedValue":"default"},{"name":"active","type":"bool","typeOptions":{"allowNulls":false},"label":"Is Active","getInitialValue":"default","getUndefinedValue":"default"},{"name":"instance","type":"reference","typeOptions":{"indexNodeKey":"/applications/1-{id}/allinstances","reverseIndexNodeKeys":["/applications/1-{id}/instances/2-{id}/users_on_this_instance"],"displayValue":"name"},"label":"Instance","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":8,"indexes":[],"allidsShardFactor":"64","collectionName":"users","isSingle":false},{"name":"instance","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"active","type":"bool","typeOptions":{"allowNulls":false},"label":"Is Active","getInitialValue":"default","getUndefinedValue":"default"},{"name":"version","type":"reference","typeOptions":{"indexNodeKey":"/applications/1-{id}/all_versions","reverseIndexNodeKeys":["/applications/1-{id}/versions/3-{id}/instances_on_this_version"],"displayValue":"name"},"label":"Version","getInitialValue":"default","getUndefinedValue":"default"},{"name":"datastoreconfig","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"Datastore Config","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[{"name":"users_on_this_instance","type":"index","map":"return {...record};","filter":"","indexType":"reference","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":15}],"allidsShardFactor":1,"collectionName":"instances","isSingle":false},{"name":"version","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":200,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":3,"indexes":[{"name":"instances_for_this_version","type":"index","map":"return {name:record.name};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":9},{"name":"instances_on_this_version","type":"index","map":"return {...record};","filter":"","indexType":"reference","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":10}],"allidsShardFactor":1,"collectionName":"versions","isSingle":false},{"name":"session","type":"record","fields":[{"name":"created","type":"number","typeOptions":{"minValue":0,"maxValue":99999999999999,"decimalPlaces":0},"label":"Created","getInitialValue":"default","getUndefinedValue":"default"},{"name":"user_json","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User Json","getInitialValue":"default","getUndefinedValue":"default"},{"name":"instanceDatastoreConfig","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"Instance Datastore Config","getInitialValue":"default","getUndefinedValue":"default"},{"name":"username","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":16,"indexes":[],"allidsShardFactor":1,"collectionName":"sessions","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[{"name":"allinstances","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":23},{"name":"sessions_by_user","type":"index","map":"return {username:record.username};","filter":"","indexType":"ancestor","getShardName":"return record.username.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[16],"nodeId":24},{"name":"user_name_lookup","type":"index","map":"return {name:record.name, instanceDatastoreConfig:instance.datastoreconfig};","filter":"","indexType":"ancestor","getShardName":"return record.name.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[8],"nodeId":25},{"name":"all_versions","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[3],"nodeId":26}],"allidsShardFactor":64,"collectionName":"applications","isSingle":false},{"name":"mastersession","type":"record","fields":[{"name":"user_json","type":"string","typeOptions":{"maxLength":10000,"values":null,"allowDeclaredValuesOnly":false},"label":"User Json","getInitialValue":"default","getUndefinedValue":"default"},{"name":"username","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":17,"indexes":[],"allidsShardFactor":64,"collectionName":"sessions","isSingle":false}],"pathMaps":[],"indexes":[{"name":"all_applications","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":22},{"name":"mastersessions_by_user","type":"index","map":"return {username:record.username};","filter":"","indexType":"ancestor","getShardName":"return record.username.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[17],"nodeId":27}],"nodeId":0},"actions":{},"triggers":[]} \ No newline at end of file +{ + "hierarchy": { + "name": "root", + "type": "root", + "children": [ + { + "name": "application", + "type": "record", + "fields": [ + { + "name": "name", + "type": "string", + "typeOptions": { + "maxLength": 500, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Name", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "domain", + "type": "string", + "typeOptions": { + "maxLength": 500, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "domain", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "application_resolve_strategy", + "type": "string", + "typeOptions": { + "maxLength": 100, + "values": [ + "domain", + "path" + ], + "allowDeclaredValuesOnly": true + }, + "label": "Resolve Application By", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [ + { + "name": "user", + "type": "record", + "fields": [ + { + "name": "unique_name", + "type": "string", + "typeOptions": { + "maxLength": 200, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Name (unique)", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "active", + "type": "bool", + "typeOptions": { + "allowNulls": false + }, + "label": "Is Active", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "instance", + "type": "reference", + "typeOptions": { + "indexNodeKey": "/applications/1-{id}/allinstances", + "reverseIndexNodeKeys": [ + "/applications/1-{id}/instances/2-{id}/users_on_this_instance" + ], + "displayValue": "name" + }, + "label": "Instance", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 8, + "indexes": [], + "allidsShardFactor": "64", + "collectionName": "users", + "isSingle": false + }, + { + "name": "instance", + "type": "record", + "fields": [ + { + "name": "name", + "type": "string", + "typeOptions": { + "maxLength": 1000, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Name", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "active", + "type": "bool", + "typeOptions": { + "allowNulls": false + }, + "label": "Is Active", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "version", + "type": "reference", + "typeOptions": { + "indexNodeKey": "/applications/1-{id}/all_versions", + "reverseIndexNodeKeys": [ + "/applications/1-{id}/versions/3-{id}/instances_on_this_version" + ], + "displayValue": "name" + }, + "label": "Version", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "datastoreconfig", + "type": "string", + "typeOptions": { + "maxLength": 1000, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Datastore Config", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 2, + "indexes": [ + { + "name": "users_on_this_instance", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "reference", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [], + "nodeId": 15 + } + ], + "allidsShardFactor": 1, + "collectionName": "instances", + "isSingle": false + }, + { + "name": "version", + "type": "record", + "fields": [ + { + "name": "name", + "type": "string", + "typeOptions": { + "maxLength": 200, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Name", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 3, + "indexes": [ + { + "name": "instances_for_this_version", + "type": "index", + "map": "return {name:record.name};", + "filter": "", + "indexType": "ancestor", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [], + "nodeId": 9 + }, + { + "name": "instances_on_this_version", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "reference", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [], + "nodeId": 10 + } + ], + "allidsShardFactor": 1, + "collectionName": "versions", + "isSingle": false + }, + { + "name": "session", + "type": "record", + "fields": [ + { + "name": "created", + "type": "number", + "typeOptions": { + "minValue": 0, + "maxValue": 99999999999999, + "decimalPlaces": 0 + }, + "label": "Created", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "user_json", + "type": "string", + "typeOptions": { + "maxLength": null, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "User Json", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "instanceDatastoreConfig", + "type": "string", + "typeOptions": { + "maxLength": null, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Instance Datastore Config", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "username", + "type": "string", + "typeOptions": { + "maxLength": null, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "User", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 16, + "indexes": [], + "allidsShardFactor": 1, + "collectionName": "sessions", + "isSingle": false + } + ], + "validationRules": [], + "nodeId": 1, + "indexes": [ + { + "name": "allinstances", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "ancestor", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 2 + ], + "nodeId": 23 + }, + { + "name": "sessions_by_user", + "type": "index", + "map": "return {username:record.username};", + "filter": "", + "indexType": "ancestor", + "getShardName": "return record.username.substring(0,2)", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 16 + ], + "nodeId": 24 + }, + { + "name": "user_name_lookup", + "type": "index", + "map": "return {name:record.name, instanceDatastoreConfig:instance.datastoreconfig};", + "filter": "", + "indexType": "ancestor", + "getShardName": "return record.name.substring(0,2)", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 8 + ], + "nodeId": 25 + }, + { + "name": "all_versions", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "ancestor", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 3 + ], + "nodeId": 26 + } + ], + "allidsShardFactor": 64, + "collectionName": "applications", + "isSingle": false + }, + { + "name": "mastersession", + "type": "record", + "fields": [ + { + "name": "user_json", + "type": "string", + "typeOptions": { + "maxLength": 10000, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "User Json", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "username", + "type": "string", + "typeOptions": { + "maxLength": null, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "User", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 17, + "indexes": [], + "allidsShardFactor": 64, + "collectionName": "sessions", + "isSingle": false + } + ], + "pathMaps": [], + "indexes": [ + { + "name": "all_applications", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "ancestor", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 1 + ], + "nodeId": 22 + }, + { + "name": "mastersessions_by_user", + "type": "index", + "map": "return {username:record.username};", + "filter": "", + "indexType": "ancestor", + "getShardName": "return record.username.substring(0,2)", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 17 + ], + "nodeId": 27 + } + ], + "nodeId": 0 + }, + "actions": { + "initialise_instance": { + "name": "initialise_instance", + "behaviourSource": "main", + "behaviourName": "initialiseInstance", + "initialOptions": {} + } + }, + "triggers": [ + { + "actionName": "initialise_instance", + "eventName": "recordApi:save:onRecordCreated", + "optionsCreator": "return { instance:context.record, apis };", + "condition": "context.record.type === \"instance\"" + } + ] +} \ No newline at end of file diff --git a/packages/server/appPackages/master/main.js b/packages/server/appPackages/master/main.js index a5f106176..2ac149734 100644 --- a/packages/server/appPackages/master/main.js +++ b/packages/server/appPackages/master/main.js @@ -2,24 +2,26 @@ const { tmpdir } = require("os"); const { join } = require("path"); const uuid = require("uuid/v1"); const { take, takeRight } = require("lodash/fp"); -const { splitKey, $ } = require("budibase-core").common; +const { splitKey, $, joinKey } = require("budibase-core").common; const { unzipTarGzPackageToRuntime } = require("../../utilities/targzAppPackage"); const { getRuntimePackageDirectory } = require("../../utilities/runtimePackages"); const { exists } = require("../../utilities/fsawait"); const createInstanceDb = require("../../initialise/createInstanceDb"); +const { createWriteStream } = require("fs"); module.exports = (config) => ({ initialiseInstance : async ({ instance, apis }) => { - const appKey = $(instance.key, [ splitKey, - take(2) + take(2), + joinKey ]); const application = await apis.recordApi.load(appKey); + const datastoreModule = require(`../../../datastores/datastores/${config.datastore}`); const dbConfig = await createInstanceDb( - require(config.datastore), + datastoreModule, config.datastoreConfig, application.id, instance.id @@ -27,7 +29,8 @@ module.exports = (config) => ({ const versionId = $(instance.version.key, [ splitKey, - takeRight(1) + takeRight(1), + joinKey ]); const runtimeDir = getRuntimePackageDirectory( @@ -35,7 +38,7 @@ module.exports = (config) => ({ versionId); if(!await exists(runtimeDir)) - await downloadAppPackage(instance, application.name, versionId); + await downloadAppPackage(apis, instance, application.name, versionId); instance.datastoreconfig = JSON.stringify(dbConfig); instance.isNew = false; @@ -43,12 +46,11 @@ module.exports = (config) => ({ } }); -const downloadAppPackage = async (instance, appName, versionId) => { - const inputStream = apis.recordApi.downloadFile(instance.key, "package.tar.gz"); +const downloadAppPackage = async (apis, instance, appName, versionId) => { + const inputStream = await apis.recordApi.downloadFile(instance.version.key, "package.tar.gz"); const tempFilePath = join(tmpdir(), `bbpackage_${uuid()}.tar.gz`); - const outputStream = await app.datastore.writableFileStream( - tempFilePath); + const outputStream = createWriteStream(tempFilePath); await new Promise((resolve,reject) => { inputStream.pipe(outputStream); diff --git a/packages/server/appPackages/testApp/dist/package.tar.gz b/packages/server/appPackages/testApp/dist/package.tar.gz index 3d913d83a555ee21a2053252f8213a9c7f2e8b23..35f3f0edfcf40198eae0ff1a694ad070b2b3decf 100644 GIT binary patch literal 1500 zcmV<21ta<&iwFP!000003hi23bJ{o*?oaXfshwfL=3-LzshiC1WG`ta-S(x!c!VuL zTVZ)6I|-BFzweQ62xAP!hBjODLTu?=bK2^2rQ&GWP8Mz#LfV{tqDp zG{fu;`*MBrs%(!ReE*;IcL)o_YX(N6)>wjw<0) z(N86uD!HkIPem^Y979sawCcL4j8#QHm9eVis4_++o?4R)t9Yf1ti%IlWIL_hOGG>u zKW)-1kO&}h5=wirv?VGXLWwA~RsSADQ?MVvCrj~Tc^swx4n($Pk+vygUqio!O?H}) z$MVSIUR*A0=GnoV2s@oVmVFK{*5d3b;NC(QzR zXoeFfZohXJrPv8_ZjnYxIeE6@)wrdnZX6k_Z{6))Mt(qM+~6tkh}_a|a{e<1-GRAv z{_C2T^WQnfvpy#n@W+`0P-Z7U&R75lnxbm_03_uV>Ljc>67gE~Np?a~$8|+ZTvHLlidhbzC ze~PHUtCmjD1XEyt7Ym!=;8w;rqS4~0vzelh2Jze{Ksrc(gq1QY@hwr?WeY^Svnig5 zYe02nhir}oqYu~y^`Z96mX!=LRfE2)b@UO;j!Ucyc&Hk8A1k4~TPvphvaDn5xHvYW zVtGhVh93Dh#CGM_?ADA;?R6~qO+z~kW%)s|V8R&P)<4ql4wMz!O5Fq}1>9t7fo~PcC^T#Js}M}kZ9#jtOf8G7QN6S_tD%q`M`1+V zNaOpEMj1AaJJ?%SA6>O#_oVNoA6)Tqj=1|P>^kGX+UiS)&bqU^bq+{Z5%CeCnc{5E zOE;-G_y*AU9`O6SOO3QAZZI>}C%TH6ari-Ke{Ouv>}sOwq5zKnOva-(CA0Gd-c2f4 zyG|vaDbu@Zrf*cT0;tOTk)C)L$d5uP2)U;{x7+PFl~+GU$xH(*fkID2{JkA`U`PZi z33w!L7!Tsei@CLl#0E5*aXf=A;y2Dhe~nA*5xe)%y1U4voPFkCRg7O|0eGoczZ<{` zQmHxos$1flNdzA`U*Yh*)*Lo-8z>afA2Nb7#ci)JZc8q0_QbAaFiPT0{#_cvkq8+@ z=ZN691+{YO=2>@FcKjH%W~lmNxKf^EkB%JWGz-#a zGkJdr3@@LKPcvL1f>X;l^#8xD{%~knL(MP^vu9oY|NAm7<1#Mel;c0I{9WAuGyni% CeC0v_ literal 1500 zcmV<21ta<&iwFP!000003hi3mbJ{o%@1NrFQ#-?f4FOW_sh7;%?BNv|NT~$ZG2OL@rPwugTcU%zcBK@>cQ^yt^S48 zv+bc_S;L;yHD2{kpxdiRgouMGb@}9tdm#h4E*8R}_yJSV{zovsc^NzQzi;;k>HZHP z1PsgW4lm^T=2h7oKluJXn`-OL(U)h_M{{hBO!nwwZnn$-^EnZMFkelFi$G4h9HS5$ z9J`Eru*_#3{sS*yrh|fj5*LM%q+|c|OuVJJY-N;D;2lWmVTuo<1ZBNL=&D)Si3H}N zb6L~mt!%2KtjhE=>$Mpoj1GP14K?j$0< zho9DI=17DPISHjRSvV4v_Mt?SI=X-NqAA!9;FG2Jp*#-Ke+wczvPe6Wv9D23!zL$9 z$U}MLaZi;Chxtx;PlS_BAId(57b|hjlyM~@S<<|O)P@29kDNeCgm@lMNGVZ}oca9~ zI5Ywz#G}lI&E=96Cu_ar3>)D8+7=bBi=m%E_}GFUKu2b>qlde(P@cJn{oF;~GziPvn+>0ZRMdb~Tb~yHDZ$iRJ6gs+ z*+LO=;?I)j_kpU@pv4?L{fYfqcyEsSmIVlcXarz8@*_%HCR8u>c#U0(IQBlrQ}2BW z>Q50Bc-b;3nqUg-Zj>Cv} zvBq~1jWcYlI@lY}99_1Qd(!vP51#mVkGS_M>^kGXdT=2jI_u7ES2-YEMZ`ylW{R^t zFWsc(;2S{Wd%*ASE;Z7gxWUX=o#-lN#{LJP-MR5Ov#W`!i$Xa5GZ~Nml*~>Sc-N_5 z<0_SWqD=4VnZ8!Z3ZN?UM|$F&qaY5YFyg-P+-|p3DldPIlbMEC0)?4~_pYJ z67WdgFdnMNQ{37_Vgs7ZIG#Zl@f&ARu)-zwh`qab-EC}A&OW=pEXFUp0K9ap-wt2} zsni^P)h+SOBtn4PuW4;jIU;lrJ$gtqQ5B)tc>@nOuABm6_@~%v-JXqxmH3-}U4qeiEye^y*Xc@OEuL zox(1eBl>|Ni60|NOOC5dR0F9QU&+dAlS;6nkmNvI`6Mseeiuzu*))i=qIXrj+Sals z?Wc_<%kKIPRmT0=8+1D8wFkRT2Sq8Iev~Lk;hiE2(LQ%NYXAU`5A0pN_v&q8*Xona z4ujGtON&^+Z?mDh$bp{Ut6v2o2Hy#4|FeF#?;YN%H(XNx z_a$ezyW|vxO?l0cH_3mYG-it{jFXGJ7m;VSo@d={+3{o4nxXEC;Zl2&Jvwr=(=14z z&E)+hFg$-cKF;un2#+me@BjbqTUKv4G%VY)?ZNr~zt7`5&f`3eIsOB1`hTMUGynjw Ce)ehr diff --git a/packages/server/initialise/createInstanceDb.js b/packages/server/initialise/createInstanceDb.js index a5486abe1..d0996c0a7 100644 --- a/packages/server/initialise/createInstanceDb.js +++ b/packages/server/initialise/createInstanceDb.js @@ -3,14 +3,8 @@ const { setupDatastore } = require("budibase-core"); const constructHierarchy = require("../utilities/constructHierarchy"); -const getDatabaseManager = require("../utilities/databaseManager"); -const { - getApisForUser, - getApisWithFullAccess -} = require("../utilities/budibaseApi"); +const getDatabaseManager = require("../utilities/databaseManager"); const masterDbAppDefinition = require("../appPackages/master/appDefinition.json"); -const masterDbAccessLevels = require("../appPackages/master/access_levels.json"); -const { masterAppPackage } = require("../utilities/createAppPackage"); module.exports = async (datastoreModule, rootDatastoreConfig, appId, instanceId) => { try { diff --git a/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/access_levels.json b/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/access_levels.json new file mode 100644 index 000000000..ebb7ca11a --- /dev/null +++ b/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/access_levels.json @@ -0,0 +1 @@ +{"levels":[{"name":"owner","permissions":[{"type":"create record","nodeKey":"/applications/1-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}"},{"type":"create record","nodeKey":"/applications/1-{id}/users/8-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}/users/8-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}/users/8-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}/users/8-{id}"},{"type":"create record","nodeKey":"/applications/1-{id}/instances/2-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}/instances/2-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}/instances/2-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}/instances/2-{id}"},{"type":"create record","nodeKey":"/applications/1-{id}/versions/3-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}/versions/3-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}/versions/3-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}/versions/3-{id}"},{"type":"create record","nodeKey":"/applications/1-{id}/sessions/16-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}/sessions/16-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}/sessions/16-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}/sessions/16-{id}"},{"type":"create record","nodeKey":"/sessions/17-{id}"},{"type":"update record","nodeKey":"/sessions/17-{id}"},{"type":"delete record","nodeKey":"/sessions/17-{id}"},{"type":"read record","nodeKey":"/sessions/17-{id}"},{"type":"read index","nodeKey":"/mastersessions_by_user"},{"type":"read index","nodeKey":"/all_applications"},{"type":"read index","nodeKey":"/applications/1-{id}/allinstances"},{"type":"read index","nodeKey":"/applications/1-{id}/sessions_by_user"},{"type":"read index","nodeKey":"/applications/1-{id}/user_name_lookup"},{"type":"read index","nodeKey":"/applications/1-{id}/all_versions"},{"type":"read index","nodeKey":"/applications/1-{id}/instances/2-{id}/users_on_this_instance"},{"type":"read index","nodeKey":"/applications/1-{id}/versions/3-{id}/instances_for_this_version"},{"type":"read index","nodeKey":"/applications/1-{id}/versions/3-{id}/instances_on_this_version"},{"type":"write templates"},{"type":"create user"},{"type":"set password"},{"type":"create temporary access"},{"type":"enable or disable user"},{"type":"write access levels"},{"type":"list users"},{"type":"list access levels"},{"type":"manage index"},{"type":"manage collection"},{"type":"set user access levels"}]}],"version":0} \ No newline at end of file diff --git a/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/appDefinition.json b/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/appDefinition.json new file mode 100644 index 000000000..61f0510f5 --- /dev/null +++ b/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/appDefinition.json @@ -0,0 +1 @@ +{"hierarchy":{"name":"root","type":"root","children":[{"name":"application","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":500,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"domain","type":"string","typeOptions":{"maxLength":500,"values":null,"allowDeclaredValuesOnly":false},"label":"domain","getInitialValue":"default","getUndefinedValue":"default"},{"name":"application_resolve_strategy","type":"string","typeOptions":{"maxLength":100,"values":["domain","path"],"allowDeclaredValuesOnly":true},"label":"Resolve Application By","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"user","type":"record","fields":[{"name":"unique_name","type":"string","typeOptions":{"maxLength":200,"values":null,"allowDeclaredValuesOnly":false},"label":"Name (unique)","getInitialValue":"default","getUndefinedValue":"default"},{"name":"active","type":"bool","typeOptions":{"allowNulls":false},"label":"Is Active","getInitialValue":"default","getUndefinedValue":"default"},{"name":"instance","type":"reference","typeOptions":{"indexNodeKey":"/applications/1-{id}/allinstances","reverseIndexNodeKeys":["/applications/1-{id}/instances/2-{id}/users_on_this_instance"],"displayValue":"name"},"label":"Instance","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":8,"indexes":[],"allidsShardFactor":"64","collectionName":"users","isSingle":false},{"name":"instance","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"active","type":"bool","typeOptions":{"allowNulls":false},"label":"Is Active","getInitialValue":"default","getUndefinedValue":"default"},{"name":"version","type":"reference","typeOptions":{"indexNodeKey":"/applications/1-{id}/all_versions","reverseIndexNodeKeys":["/applications/1-{id}/versions/3-{id}/instances_on_this_version"],"displayValue":"name"},"label":"Version","getInitialValue":"default","getUndefinedValue":"default"},{"name":"datastoreconfig","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"Datastore Config","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[{"name":"users_on_this_instance","type":"index","map":"return {...record};","filter":"","indexType":"reference","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":15}],"allidsShardFactor":1,"collectionName":"instances","isSingle":false},{"name":"version","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":200,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"package","type":"file","typeOptions":{},"label":"Package","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":3,"indexes":[{"name":"instances_for_this_version","type":"index","map":"return {name:record.name};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":9},{"name":"instances_on_this_version","type":"index","map":"return {...record};","filter":"","indexType":"reference","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":10}],"allidsShardFactor":1,"collectionName":"versions","isSingle":false},{"name":"session","type":"record","fields":[{"name":"created","type":"number","typeOptions":{"minValue":0,"maxValue":99999999999999,"decimalPlaces":0},"label":"Created","getInitialValue":"default","getUndefinedValue":"default"},{"name":"user_json","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User Json","getInitialValue":"default","getUndefinedValue":"default"},{"name":"instanceDatastoreConfig","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"Instance Datastore Config","getInitialValue":"default","getUndefinedValue":"default"},{"name":"username","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":16,"indexes":[],"allidsShardFactor":1,"collectionName":"sessions","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[{"name":"allinstances","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":23},{"name":"sessions_by_user","type":"index","map":"return {username:record.username};","filter":"","indexType":"ancestor","getShardName":"return record.username.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[16],"nodeId":24},{"name":"user_name_lookup","type":"index","map":"return {name:record.name, instanceDatastoreConfig:instance.datastoreconfig};","filter":"","indexType":"ancestor","getShardName":"return record.name.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[8],"nodeId":25},{"name":"all_versions","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[3],"nodeId":26}],"allidsShardFactor":64,"collectionName":"applications","isSingle":false},{"name":"mastersession","type":"record","fields":[{"name":"user_json","type":"string","typeOptions":{"maxLength":10000,"values":null,"allowDeclaredValuesOnly":false},"label":"User Json","getInitialValue":"default","getUndefinedValue":"default"},{"name":"username","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":17,"indexes":[],"allidsShardFactor":64,"collectionName":"sessions","isSingle":false}],"pathMaps":[],"indexes":[{"name":"all_applications","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":22},{"name":"mastersessions_by_user","type":"index","map":"return {username:record.username};","filter":"","indexType":"ancestor","getShardName":"return record.username.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[17],"nodeId":27}],"nodeId":0},"actions":{},"triggers":[]} \ No newline at end of file diff --git a/packages/server/tests/createNewApp.js b/packages/server/tests/createNewApp.js index 8d216e3b5..07449fe8b 100644 --- a/packages/server/tests/createNewApp.js +++ b/packages/server/tests/createNewApp.js @@ -57,6 +57,7 @@ module.exports = (app) => { }); + let instance1Key; it("should be able to create new instance of app", async () => { const master = await getmaster(); const instance1 = master.recordApi @@ -64,7 +65,11 @@ module.exports = (app) => { instance1.name = "instance 1"; instance1.active = true; instance1.version = {key:version1Key, name:"v1"}; - instance1.datastoreconfig; + instance1Key = instance1.key; + + await app.post(`/_master/api/record/${instance1.key}`, instance1) + .set("cookie", app.masterAuth.cookie) + .expect(statusCodes.OK); }); diff --git a/packages/server/tests/testApp.js b/packages/server/tests/testApp.js index 93c37a281..8fffaba32 100644 --- a/packages/server/tests/testApp.js +++ b/packages/server/tests/testApp.js @@ -11,7 +11,7 @@ const masterOwnerName = "test_master"; const masterOwnerPassword = "test_master_pass"; const extraMasterPlugins = { - main: { + test_plugins: { outputToFile : ({filename, content}) => { fs.writeFile(`./tests/.data/${filename}`, content, {encoding:"utf8"}); } @@ -22,7 +22,7 @@ const customizeMaster = appDefinition => { appDefinition.actions.outputToFile = { name: 'outputToFile', - behaviourSource: 'main', + behaviourSource: 'test_plugins', behaviourName: 'outputToFile', initialOptions: {} }; diff --git a/packages/server/utilities/runtimePackages.js b/packages/server/utilities/runtimePackages.js index d7859d489..4b21e6592 100644 --- a/packages/server/utilities/runtimePackages.js +++ b/packages/server/utilities/runtimePackages.js @@ -2,7 +2,14 @@ const { join } = require("path"); const runtimePackagesDirectory = "./runtime_apps"; +const getRuntimeAppsDirectory = (appName) => + join(runtimePackagesDirectory, appName); + module.exports.runtimePackagesDirectory = runtimePackagesDirectory; module.exports.getRuntimePackageDirectory = (appName, versionId) => - join(runtimePackagesDirectory, appName, versionId); + join( + getRuntimeAppsDirectory(appName), + versionId); + +module.exports.getRuntimeAppsDirectory = getRuntimeAppsDirectory; diff --git a/packages/server/utilities/targzAppPackage.js b/packages/server/utilities/targzAppPackage.js index 684457fa3..b35f3f08a 100644 --- a/packages/server/utilities/targzAppPackage.js +++ b/packages/server/utilities/targzAppPackage.js @@ -6,7 +6,7 @@ const tar = require('tar-fs'); const zlib = require("zlib"); const { join, dirname, sep } = require("path"); const { exists, mkdir, unlink, stat } = require("../utilities/fsawait"); -const { getRuntimePackageDirectory } = require("./runtimePackages"); +const { getRuntimePackageDirectory, getRuntimeAppsDirectory } = require("./runtimePackages"); module.exports.createTarGzPackage = async (config, appName) => { @@ -29,14 +29,19 @@ module.exports.createTarGzPackage = async (config, appName) => { module.exports.unzipTarGzPackageToRuntime = async (src, appName, versionId) => { const versionDir = getRuntimePackageDirectory(appName, versionId); - - if(await exists(versionDir)) { - await rimraf(versionDir); + const appDir = getRuntimeAppsDirectory(appName); + + if(await exists(appDir)) { + if(await exists(versionDir)) { + await rimraf(versionDir); + } + } else { + await mkdir(appDir); } await mkdir(versionDir); - decompress(src, versionDir); + await decompress(src, versionDir); } const compress = (src, dest) => new Promise((resolve, reject) => {