decentralized-internet
Version:
An NPM library of programs to create decentralized web and distributed computing projects
1 lines • 10 kB
JavaScript
;var request=require("request"),fs=require("fs"),Promise=require("bluebird"),path=require("path"),_=require("underscore"),Joi=require("@hapi/joi"),clustermodel=require("clusterpost-model"),qs=require("querystring"),prompt=require("prompt"),os=require("os"),jws=require("jsonwebtoken"),HapiJWTCouch=require("hapi-jwt-couch-lib");class ClusterpostLib extends HapiJWTCouch{constructor(){super(),this.configfilename=path.join(process.cwd(),".clusterpost-config.json"),this.joiconf=Joi.object().keys({uri:Joi.string().uri(),token:Joi.string()}),this.joiokres=Joi.object().keys({ok:Joi.boolean().valid(!0),id:Joi.string(),rev:Joi.string()})}setConfigFileName(e){this.configfilename=e}getConfigFileName(){return this.configfilename}setClusterPostServer(e){this.setServer(e)}getClusterPostServer(){return this.getServer()}getConfigFile(){try{var e=JSON.parse(fs.readFileSync(this.getConfigFileName()));return Joi.assert(e,this.joiconf),e}catch(e){return null}}setConfigFile(e){try{var t=this.configfilename;console.log("Writing configuration file",t),fs.writeFileSync(t,JSON.stringify(e))}catch(e){console.error(e)}}getExecutionServers(){var e=this;return new Promise(function(t,r){var n={url:e.getServer()+"/executionserver",method:"GET",agentOptions:e.agentOptions,auth:e.auth};request(n,function(e,n,o){e?r(e):t(JSON.parse(o))})})}createDocument(e){var t=this;return new Promise(function(r,n){var o={url:t.getServer()+"/dataprovider",method:"POST",json:e,agentOptions:t.agentOptions,auth:t.auth};request(o,function(e,t,o){e?n(e):200!==t.statusCode?(console.error(e),n(o)):r(o)})})}getDocument(e){Joi.assert(e,Joi.string().alphanum());var t=this;return new Promise(function(r,n){var o={url:t.getServer()+"/dataprovider/"+e,method:"GET",agentOptions:t.agentOptions,auth:t.auth};request(o,function(e,t,o){e?n(e):r(JSON.parse(o))})})}updateDocument(e){Joi.assert(e,clustermodel.job);var t=this;return new Promise(function(r,n){try{var o={uri:t.getServer()+"/dataprovider",method:"PUT",json:e,agentOptions:t.agentOptions,auth:t.auth};request(o,function(e,t,n){e&&r(e),r(n)})}catch(e){n(e)}})}updateDocuments(e){var t=this;return Promise.map(e,function(e){return t.updateDocument(e)},{concurrency:1})}getUserJobs(e){var t=this;return new Promise(function(r,n){var o={url:t.getServer()+"/dataprovider/user?"+qs.stringify(e),method:"GET",agentOptions:t.agentOptions,auth:t.auth};request(o,function(e,t,o){e?n(e):r(JSON.parse(o))})})}getJobs(e,t,r){var n={};return e&&(n.executable=e),t&&(n.jobstatus=t),r&&(n.userEmail=r),this.getUserJobs(n)}getExecutionServerJobs(e,t){var r={};return e&&(r.executionserver=e),t&&(r.jobstatus=t),this.getUserJobs(r)}getDocumentAttachment(e,t){Joi.assert(e,Joi.string().alphanum()),Joi.assert(t,Joi.string());var r=this;return new Promise(function(n,o){var i={url:r.getServer()+"/dataprovider/"+e+"/"+t,method:"GET",agentOptions:r.agentOptions,auth:r.auth};request(i,function(e,t,r){e?o(e):n(r)})})}getDocumentAttachmentSave(e,t,r){Joi.assert(e,Joi.string().alphanum()),Joi.assert(t,Joi.string()),Joi.assert(r,Joi.string());var n=this;return new Promise(function(o,i){try{var s={url:n.getServer()+"/dataprovider/"+e+"/"+encodeURIComponent(t),method:"GET",agentOptions:n.agentOptions,auth:n.auth},a=fs.createWriteStream(r);request(s).pipe(a),a.on("finish",function(e){e?i({path:r,status:!1,error:e}):o({path:r,status:!0})})}catch(e){i(e)}})}getDownloadToken(e,t){Joi.assert(e,Joi.string().alphanum()),Joi.assert(t,Joi.string());var r=this;return new Promise(function(n,o){var i={url:r.getServer()+"/dataprovider/download/"+e+"/"+t,method:"GET",agentOptions:r.agentOptions,auth:r.auth};request(i,function(e,t,r){e?o(e):n(JSON.parse(r))})})}downloadAttachment(e){Joi.assert(e,Joi.string());var t=this;return new Promise(function(r,n){var o={url:t.getServer()+"/dataprovider/download/"+e,method:"GET",agentOptions:t.agentOptions};request(o,function(e,t,o){e?n(e):r(o)})})}downloadJob(e,t){var r=this;return new Promise(function(n,o){var i={url:r.getServer()+"/dataprovider/download/job/"+e,method:"GET",agentOptions:r.agentOptions,auth:r.auth},s=fs.createWriteStream(t);request(i).pipe(s),s.on("finish",function(e){e?o({path:t,status:!1,error:e}):n({path:t,status:!0})})})}uploadFile(e,t,r){Joi.assert(e,Joi.string().alphanum()),Joi.assert(t,Joi.string());var n=this;return new Promise(function(o,i){r=void 0===r?path.basename(t):encodeURIComponent(r);try{var s={url:n.getServer()+"/dataprovider/"+e+"/"+r,method:"PUT",agentOptions:n.agentOptions,headers:{"Content-Type":"application/octet-stream"},auth:n.auth};if(fs.statSync(t))fs.createReadStream(t).pipe(request(s,function(e,t,r){e?i(e):o(JSON.parse(r))}));else i({error:"File not found: "+t})}catch(e){i(e)}})}uploadFiles(e,t,r){var n=this;return Promise.map(t,function(t,o){return void 0!==r?n.uploadFile(e,t,r[o]):n.uploadFile(e,t)},{concurrency:1}).then(function(e){return e})}executeJob(e,t){Joi.assert(e,Joi.string().alphanum());var r=this;return new Promise(function(n,o){try{var i={url:r.getServer()+"/executionserver/"+e,json:{force:t},method:"POST",agentOptions:r.agentOptions,auth:r.auth};request(i,function(e,t,r){e?o(e):n(r)})}catch(e){o(e)}})}updateJobStatus(e){Joi.assert(e,Joi.string().alphanum());var t=this;return new Promise(function(r,n){try{var o={url:t.getServer()+"/executionserver/"+e,method:"GET",agentOptions:t.agentOptions,auth:t.auth};request(o,function(e,t,o){e?n(e):r(JSON.parse(o))})}catch(e){n(e)}})}killJob(e){Joi.assert(e,Joi.string().alphanum());var t=this;return new Promise(function(r,n){var o={url:t.getServer()+"/executionserver/"+e,method:"DELETE",agentOptions:t.agentOptions,auth:t.auth};request(o,function(e,t,o){e?n(e):r(JSON.parse(o))})})}deleteJob(e){Joi.assert(e,Joi.string().alphanum());var t=this;return new Promise(function(r,n){var o={url:t.getServer()+"/dataprovider/"+e,method:"DELETE",agentOptions:t.agentOptions,auth:t.auth};request(o,function(e,t,o){e?n(e):r(JSON.parse(o))})})}checkFiles(e){return Promise.map(e,function(e){if(fs.statSync(e))return!0})}createAndSubmitJob(e,t,r){var n=this;return Promise.all([this.getUser(),this.getExecutionServers()]).spread(function(o,i){return e.userEmail||(e.userEmail=o.email),e.executionserver||(e.executionserver=i[0].name),(t?n.checkFiles(t).then(function(){return n.createDocument(e)}).then(function(e){var o=e.id;return n.uploadFiles(o,t,r).then(function(){return o})}):n.createDocument(e).then(function(e){return e.id})).then(function(e){return n.executeJob(e).then(function(t){return e})})})}mkdirp(e){var t=path.parse(e),r=e.split(path.sep),n=t.root;_.each(r,function(e){n=path.join(n,e);try{fs.statSync(n)}catch(e){try{fs.mkdirSync(n)}catch(e){throw console.error(e),e}}})}getJobOutputs(e,t){var r=e.outputs,n=this;return Promise.map(r,function(r){var o=r.name;if("tar.gz"===r.type&&"./"===o?o=e._id+".tar.gz":"tar.gz"===r.type&&".tar.gz"!==path.parse(o).ext&&(o=r.name+".tar.gz"),0===o.indexOf("./")&&(o=o.slice(2)),t){var i=path.join(t,o);return console.log("Downloading file:",i),n.mkdirp(path.parse(i).dir),n.getDocumentAttachmentSave(e._id,o,i)}return n.getDocumentAttachment(e._id,o)})}getDeleteQueue(){var e=this;return new Promise(function(t,r){var n={url:e.getServer()+"/executionserver/deletequeue",method:"GET",agentOptions:e.agentOptions,auth:e.auth};request(n,function(e,n,o){e?r(e):t(JSON.parse(o))})})}promptUsernamePassword(){return new Promise(function(e,t){prompt.start(),prompt.get({properties:{email:{pattern:/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,message:"Email address",required:!0},password:{hidden:!0,required:!0}}},function(r,n){r?t(r):e(n)})})}getExecutionServerToken(e){var t=this;return new Promise(function(r,n){var o="";e&&(Joi.assert(e,Joi.object().keys({executionserver:Joi.string()})),o="?"+qs.stringify(e));var i={url:t.getServer()+"/executionserver/tokens"+o,method:"GET",agentOptions:t.agentOptions,auth:t.auth};request(i,function(e,t,o){e?n(e):r(JSON.parse(o))})})}promptClusterpostServer(){return new Promise(function(e,t){prompt.start(),prompt.get({properties:{uri:{message:"Please enter the clusterpost server uri",required:!0}}},function(r,n){r?t(r):e(n)})})}testUserToken(e){var t=jws.decode(e.token);return!(t.exp&&t.exp<Date.now()/1e3)&&(void 0===t.exp&&console.log("WARNING! The token does not have an expiry date. Tokens without expiry date were deprecated. The clusterpost-server could be running an old version. Please contact the clusterpost-server administrator."),!0)}start(e){var t=this;e&&t.setConfigFileName(e);var r=t.getConfigFile();return r?(t.setClusterPostServer(r.uri),t.testUserToken(r)?(t.setUserToken(r),Promise.resolve()):t.promptUsernamePassword().then(function(e){return t.userLogin(e)}).then(function(e){_.extend(e,{uri:t.getClusterPostServer()}),t.setConfigFile(e)})):t.promptClusterpostServer().then(function(e){return t.setClusterPostServer(e),t.promptUsernamePassword()}).then(function(e){return t.userLogin(e)}).then(function(e){_.extend(e,{uri:t.getClusterPostServer()}),t.setConfigFile(e)})}parseCLIFromString(e){var t=e.split(" ");return this.parseCLI(t)}parseCLI(e){var t=e[0],r={},n=[],o=[],i={executable:t,parameters:_.map(e.splice(1),function(e){if(fs.existsSync(e)&&!fs.statSync(e).isDirectory()){var t=path.basename(e);return r[t]&&(t=_.uniqueId("c_")+"_"+t),r[t]=!0,n.push(e),o.push(t),{flag:"",name:t}}return{flag:"",name:e}}),inputs:_.map(o,e=>({name:e})),outputs:[{type:"directory",name:"./"},{type:"file",name:"stdout.out"},{type:"file",name:"stderr.err"}],type:"job",userEmail:"juanprietob@gmail.com"};return Promise.resolve({job:i,inputs:n,names:o})}parseCLIFromStringAndSubmit(e,t){var r=this;return r.parseCLIFromString(e).then(function(e){return t&&(e.job.executionserver=t),r.createAndSubmitJob(e.job,e.inputs,e.names)})}parseCLIAndSubmit(e,t){var r=this;return this.parseCLI(e).then(function(e){return t&&(e.job.executionserver=t),r.createAndSubmitJob(e.job,e.inputs,e.names)})}}module.exports=new ClusterpostLib;