From c8f5ae281803051337ad59ee1ac829bc9dda1141 Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 7 Jul 2016 11:33:54 -0400 Subject: [PATCH 01/49] issue 32 fixed --- private/settings.env.json | 7 +- server/imports/api/.lab.exec.js.swp | Bin 0 -> 12288 bytes server/imports/api/lab.env.js | 277 ++++++++++++++-------------- server/imports/api/lab.import.js | 10 - 4 files changed, 144 insertions(+), 150 deletions(-) create mode 100644 server/imports/api/.lab.exec.js.swp delete mode 100644 server/imports/api/lab.import.js diff --git a/private/settings.env.json b/private/settings.env.json index 17971333..9efb9e75 100644 --- a/private/settings.env.json +++ b/private/settings.env.json @@ -1,3 +1,8 @@ { - + "docker_host": "10.100.1.10", + "docker_port": "4000", + "etcd_host": "192.168.56.102", + "etcd_port": "2379", + "etcd_user": "cem", + "etcd_pass": "ersoz" } diff --git a/server/imports/api/.lab.exec.js.swp b/server/imports/api/.lab.exec.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..85a15b710ff544f7b1b72e384e53829392721294 GIT binary patch literal 12288 zcmeI2&u<$=6vwB402f-IMdCU!kgQv0Hv~|rqd=vUNRd)OMbmIAoAo%}X1!}>#`%He zg2bOdk>~{~4u})i{s9#S4sZo31S%YWiZe&x`(}6TO=`zQoKR+^Pwky~^X9$pyq$H_ zS(~}IbdH~LUtqW%XY6`-W%ckAv+QrdSRh)|I`)Fy^mbc~wYvgC?`#ruS|ZlUqhY$U z?fFr==_w&Mh4jK!JCW$~+o2cvYp&Q9fqQwp>#=iN1FOJ+R-mIB(=Q!ad4Be}8PehD z@&rGAY~?^pVw1NDSOu&CRspMkRlq7>6|f2%GzE0~5PKI%-IBu^SH|c>Mo={`dbck1=)=d<@F%;7$qgf$QKCAi-PU z7`X8;WAA|#a1vC210Ddkpv!mQTR<9p1a`nhunZOf2fsqYufR1BfUCe>RspMkRp5Xt z&`Ro^NZ=@!IoieNc`UX#4tKqZvt3SQjMk?cf`oW*eIF7?c0jJxtRypQazLL+FMUl53%K7_YNzE!?(DbfS0KSgW{> zpc|by&|wlgl`c6fl}g1X?wx?MdL+1R3NEBf0QhaJH>D~FSv3yhZ>D=iNr?CMYT7_I1d|+ zZiZ?|&~B)feWjgB1xd?fi^>d97IGYjwLw^d9k5r&NK%62(a8g}hLT~kJtZf@Vzp^il6&wQ^A zshz~!#t z=^6jbgmJiQnP_M=4P&WZMf^+kTm+t94t61w>(&M6?CRtVEwTGK$Pf9T>opm!59!Wo zF>_*k(Bz{W?CGoU$w_G6zZ}|MlLpP_nhG|vPvv{t)PDA+p2yf1Qrt5$^%&K52Q&yI zYtPFS=IMl!lO>Y@EefnjCakm+Z+Ai|oGI5sBURI7HI-@AGxq(;Z}^cibw(-#Nvsn5 z9Eg&2ryL}$HkG4!d(?ROq{uu3z7Cp>sPL|Fl{?Hr!1Q9%j~u1ba>3RncZ?~v?g?t; z{l_Ss98Um3q+c9`w_MN^!3KQg;v0YTsw)=f?o=sHs@ODF3MX@0bVG$lT^$*rx!g+P z^`yR5^D?1o!THzEp5D^pOkK^)zIf{NtlJ{L5Tj;pGdt{<F`srn literal 0 HcmV?d00001 diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index dd76befa..ba430626 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -1,6 +1,5 @@ -// Import Dockerode and Swarmerode +// Import Dockerode var dockerode = require('dockerode'); -var swarmerode = require('swarmerode'); // Import other libraries var async = require('async'); @@ -12,12 +11,20 @@ var nconf = require('nconf'); * intializes docker, etcd connection */ var env = function(){ + var etcd_address = nconf.get('etcd_host')+':'+nconf.get('etcd_port'); + var etcd_auth = { - user: nconf.get(etcd_user), - password: nconf.get(etcd_pass) + user: nconf.get('etcd_user'), + password: nconf.get('etcd_pass') } - this.docker = new dockerode({host: '10.100.1.10', port: '2375'}); //TODO: nconf.get??? - this.etcd = new etcd('192.168.56.102:2379',etcd_auth); + + var docker_settings = { + host: nconf.get('docker_host'), + password: nconf.get('docker_port') + } + + this.docker = new dockerode(docker_settings); //TODO: nconf.get??? + this.etcd = new etcd(etcd_address,etcd_auth); this.root_dom = nconf.get("root_domain"); } @@ -41,27 +48,6 @@ env.prototype.start = function(){ return Promise.resolve(); } -//function wrappers for api functions for promise chaining -env.prototype.createVm = function(opts){ - var slf = this; - return (function(){ return slf.createVm1(opts); }); -} - -env.prototype.updateVm = function(vmName,opts){ - var slf = this; - return (function(){ return slf.updateVm1(vmName,opts); }); -} - -env.prototype.removeVm = function(vmName,opts){ - var slf = this; - return (function(){ return slf.removeVm1(vmName,opts); }); -} - -env.prototype.shell = function(cont,com,opts){ - var slf = this; - return (function(){ return slf.shell1(cont,com,opts) }); -} - /* deleteRecords * delete helix and redRouter records for given user * callback is optional @@ -110,13 +96,13 @@ env.prototype.init = function(opts){ * for usr: cemersoz, at time 1467752963922 * labvm = "labVm_cemersoz_1467752963922" */ - this.labVm = "labVm_"+usr+"_"+((new Date).getTime()).toString(); + this.labVm = "labVm_"+this.usr+"_"+((new Date).getTime()).toString(); var dck = this.docker; //image defaults to alpine - var img = 'alpine' - + //var img = nconf.get('default_image'); + img = 'alpine' var crtOpts = null var strOpts = null; @@ -127,11 +113,11 @@ env.prototype.init = function(opts){ } //declare final options - var crtOptsf = {Image: 'alpine',CMD: ['/bin/sh'], name: this.labVm} + var crtOptsf = {Image: img,CMD: ['/bin/sh'], name: this.labVm} //change final options according to opts input, if there is any underscore.extend(crtOptsf, crtOpts); - //this.vmList.push({name: "labVm",id:this.labVm}); + var slf = this; return new Promise(function(resolve,reject){ @@ -212,7 +198,7 @@ env.prototype.init = function(opts){ }); } }); - }); + }); } @@ -223,7 +209,7 @@ env.prototype.init = function(opts){ {dockerodeStartOptions: {--your options here--}} */ //also starts said vm -env.prototype.createVm1 = function(opts) { +env.prototype.createVm = function(opts) { var dck = this.docker; var fn1 = null; //parse container create and container start options @@ -238,7 +224,7 @@ env.prototype.createVm1 = function(opts) { var cName = "vm_"+usr+'_'+((new Date).getTime()).toString(); //image defaults to alpine - var img = 'alpine'; + var img = nconf.get('default_image');; if(crtOpt.img) img = crtOpt.img; var crtOptsf = {Image:img,CMD:['/bin/sh']} @@ -249,132 +235,145 @@ env.prototype.createVm1 = function(opts) { //this.vmList.push({name: crtOpt.name,id:cName}); //clone this into slf to use in the promise var slf = this; - return new Promise(function(resolve,reject){ + return function(){ + return new Promise(function(resolve,reject){ - //check for valid name - if(crtOpt.name == null){ - TuxLog.log('labfile_error',"name not specified for vm"); - reject("Internal error"); - } - - if(underscore.has(slf.vmList,crtOpt.name)){ - TuxLog.log('labfile_error', 'there is already a vm with this name: '+crtOpt.name); - reject("Internal error"); - } - - dck.pull(img,function(err,stream){ - if(err) { - TuxLog.log('debug', "docker pull error: "+err); - reject("Internal error"); + //check for valid name + if(crtOpt.name == null){ + TuxLog.log('labfile_error',"name not specified for vm"); + reject("Internal error"); } - else { - dck.createContainer(crtOptsf,function(err,container){ - if(err) { reject(err); } - else{ - container.start(strOpt,function(err,data){ - if(err) { reject(err); } - else{ - slf.vmList[crtOpt.name] = cName; - resolve(); - } - }); - } - }); + + if(underscore.has(slf.vmList,crtOpt.name)){ + TuxLog.log('labfile_error', 'there is already a vm with this name: '+crtOpt.name); + reject("Internal error"); } + + dck.pull(img,function(err,stream){ + if(err) { + TuxLog.log('debug', "docker pull error: "+err); + reject("Internal error"); + } + else { + dck.createContainer(crtOptsf,function(err,container){ + if(err) { + TuxLog.log('debug','docker create error: '+err); + reject("Interlan error"); + } + else{ + container.start(strOpt,function(err,data){ + if(err) { + TuxLog.log('debug','docker start error: '+err); + reject(); + } + else{ + slf.vmList[crtOpt.name] = cName; + resolve(); + } + }); + } + }); + } + }); }); - }); + } } - //takes the id or containerName of a vm and removes the vm, also removing it //from the vmList -env.prototype.removeVm1 = function (vmName,opts) { +env.prototype.removeVm = function (vmName,opts) { var slf = this; - return new Promise(function(resolve,reject){ - - //check if container initialized - if(!underscore.has(this.vmList,vmName)){ - TuxLog.log('labfile_error',"trying to delete non-existing vm"); - reject("Internal error"); - } + return function(){ + return new Promise(function(resolve,reject){ - slf.vmList[vmName].remove(opts,function(err,data){ - if(err){ - TuxLog.log('debug',"error removing container: "+err); - reject("Internal error"); + //check if container initialized + if(!underscore.has(this.vmList,vmName)){ + TuxLog.log('labfile_error',"trying to delete non-existing vm"); + reject("Internal error"); } - resolve(); - }); - }); -} - -env.prototype.updateVm1 = function(vmName, opts) { - var slf = this; - return new Promise(function(resolve,reject){ - if(!underscore.has(slf.vmList,vmName)){ - TuxLog.log('labfile_error','trying to update non-existing vm'); - reject("Internal error"); - } - else{ - slf.docker.getContainer(slf.vmList[vmName]).update(opts,function(err,data){ - if(err){ - TuxLog.log('debug','error updating container: '+err); - reject("Internal error"); - } - else{ - resolve(data); - } + slf.vmList[vmName].remove(opts,function(err,data){ + if(err){ + TuxLog.log('debug',"error removing container: "+err); + reject("Internal error"); + } + resolve(); }); - } - }); + }); + } } -env.prototype.shell1 = function(vmName,command,opts) { + +env.prototype.updateVm = function(vmName, opts) { var slf = this; - return new Promise(function(resolve,reject){ - if(!underscore.has(slf.vmList,vmName)){ - TuxLog.log('labfile_error','trying to run shell on non-existing vm'); - reject("Internal error"); - } - var options = {AttachStdout: true, AttachStderr: true, Cmd: command.split(" ")}; - this.docker.getContainer(slf.vmList[vmName]).exec(options, function(err, exec){ - if(err){ - TuxLog.log('debug','error trying to container.exec: '+err); - reject("Internal error"); + return function(){ + return new Promise(function(resolve,reject){ + if(!underscore.has(slf.vmList,vmName)){ + TuxLog.log('labfile_error','trying to update non-existing vm'); + reject("Internal error"); } else{ - exec.start({hijack: true, stdin: true, stdout: true, stderr: true}, - function(err, stream){ + slf.docker.getContainer(slf.vmList[vmName]).update(opts,function(err,data){ if(err){ - TuxLog.log('debug','error trying to exec.start: '+err); - reject("Internal error"); - } - else{ - var dat = '' - var errr = '' - var header = null; - stream.on('readable',function(){ - header = header || stream.read(8); - while(header !== null){ - var type = header.readUInt8(0); - var payload = stream.read(header.readUInt32BE(4)); - if(payload == null) break; - else{ dat += payload; } - header = stream.read(8); - } - });//TODO: split stdout and stderr - stream.on('end',function(){ - - if(err ===''){ resolve(dat); } - else{ reject(dat,err,null) } - }); - } - }); + TuxLog.log('debug','error updating container: '+err); + reject("Internal error"); + } + else{ + resolve(); + } + }); } }); - }); + } +} + +env.prototype.shell = function(vmName,command,opts) { + var slf = this; + return function(){ + return new Promise(function(resolve,reject){ + if(!underscore.has(slf.vmList,vmName)){ + TuxLog.log('labfile_error','trying to run shell on non-existing vm'); + reject("Internal error"); + } + var options = {AttachStdout: true, AttachStderr: true, Cmd: command.split(" ")}; + this.docker.getContainer(slf.vmList[vmName]).exec(options, function(err, exec){ + if(err){ + TuxLog.log('debug','error trying to container.exec: '+err); + reject("Internal error"); + } + else{ + exec.start({hijack: true, stdin: true, stdout: true, stderr: true}, + function(err, stream){ + if(err){ + TuxLog.log('debug','error trying to exec.start: '+err); + reject("Internal error"); + } + else{ + var dat = '' + var stdErr = '' + var header = null; + stream.on('readable',function(){ + header = header || stream.read(8); + while(header !== null){ + var type = header.readUInt8(0); + var payload = stream.read(header.readUInt32BE(4)); + if(payload == null) break; + else{ dat += payload; } + header = stream.read(8); + } + });//TODO: split stdout and stderr + stream.on('end',function(){ + + if(stdErr ===''){ resolve(dat); } + else{ reject(dat,stdErr,null) } + }); + } + }); + } + }); + }); + } } /* gets pass for given virtual machine diff --git a/server/imports/api/lab.import.js b/server/imports/api/lab.import.js deleted file mode 100644 index d5106150..00000000 --- a/server/imports/api/lab.import.js +++ /dev/null @@ -1,10 +0,0 @@ -var labImport = function(){} -labImport.prototype.check = function(str){ - var tux = eval(str); - assert(typeof tux.setup === 'function') - assert(typeof tux.tasks === 'function') - var tuxOrig = require('./tuxlab.js') - assert(tux.init.toString() === tuxOrig.init.toString()); - assert(tux.newTask.toString() === tuxOrig.newTask.toString()); -} -module.exports = new labImport(); From 71179a92517d8af371936f98f33999ff579cb622 Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 7 Jul 2016 11:34:08 -0400 Subject: [PATCH 02/49] removed swp --- server/imports/api/.lab.exec.js.swp | Bin 12288 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 server/imports/api/.lab.exec.js.swp diff --git a/server/imports/api/.lab.exec.js.swp b/server/imports/api/.lab.exec.js.swp deleted file mode 100644 index 85a15b710ff544f7b1b72e384e53829392721294..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2&u<$=6vwB402f-IMdCU!kgQv0Hv~|rqd=vUNRd)OMbmIAoAo%}X1!}>#`%He zg2bOdk>~{~4u})i{s9#S4sZo31S%YWiZe&x`(}6TO=`zQoKR+^Pwky~^X9$pyq$H_ zS(~}IbdH~LUtqW%XY6`-W%ckAv+QrdSRh)|I`)Fy^mbc~wYvgC?`#ruS|ZlUqhY$U z?fFr==_w&Mh4jK!JCW$~+o2cvYp&Q9fqQwp>#=iN1FOJ+R-mIB(=Q!ad4Be}8PehD z@&rGAY~?^pVw1NDSOu&CRspMkRlq7>6|f2%GzE0~5PKI%-IBu^SH|c>Mo={`dbck1=)=d<@F%;7$qgf$QKCAi-PU z7`X8;WAA|#a1vC210Ddkpv!mQTR<9p1a`nhunZOf2fsqYufR1BfUCe>RspMkRp5Xt z&`Ro^NZ=@!IoieNc`UX#4tKqZvt3SQjMk?cf`oW*eIF7?c0jJxtRypQazLL+FMUl53%K7_YNzE!?(DbfS0KSgW{> zpc|by&|wlgl`c6fl}g1X?wx?MdL+1R3NEBf0QhaJH>D~FSv3yhZ>D=iNr?CMYT7_I1d|+ zZiZ?|&~B)feWjgB1xd?fi^>d97IGYjwLw^d9k5r&NK%62(a8g}hLT~kJtZf@Vzp^il6&wQ^A zshz~!#t z=^6jbgmJiQnP_M=4P&WZMf^+kTm+t94t61w>(&M6?CRtVEwTGK$Pf9T>opm!59!Wo zF>_*k(Bz{W?CGoU$w_G6zZ}|MlLpP_nhG|vPvv{t)PDA+p2yf1Qrt5$^%&K52Q&yI zYtPFS=IMl!lO>Y@EefnjCakm+Z+Ai|oGI5sBURI7HI-@AGxq(;Z}^cibw(-#Nvsn5 z9Eg&2ryL}$HkG4!d(?ROq{uu3z7Cp>sPL|Fl{?Hr!1Q9%j~u1ba>3RncZ?~v?g?t; z{l_Ss98Um3q+c9`w_MN^!3KQg;v0YTsw)=f?o=sHs@ODF3MX@0bVG$lT^$*rx!g+P z^`yR5^D?1o!THzEp5D^pOkK^)zIf{NtlJ{L5Tj;pGdt{<F`srn From 9c68e125dcdf0014f3e7b3c9d47f5e0b0b8647aa Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 7 Jul 2016 11:40:11 -0400 Subject: [PATCH 03/49] fixed nconf issues --- private/settings.env.json | 3 ++- server/imports/api/lab.env.js | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/private/settings.env.json b/private/settings.env.json index 9efb9e75..2db160a8 100644 --- a/private/settings.env.json +++ b/private/settings.env.json @@ -4,5 +4,6 @@ "etcd_host": "192.168.56.102", "etcd_port": "2379", "etcd_user": "cem", - "etcd_pass": "ersoz" + "etcd_pass": "ersoz", + "default_image": "alpine" } diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index ba430626..7fa386cd 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -101,8 +101,7 @@ env.prototype.init = function(opts){ var dck = this.docker; //image defaults to alpine - //var img = nconf.get('default_image'); - img = 'alpine' + var img = nconf.get('default_image'); var crtOpts = null var strOpts = null; From 4c41fd475bcbe2c74e181df23e65418a9da9a2c9 Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 7 Jul 2016 11:52:52 -0400 Subject: [PATCH 04/49] issue 82, 84 fixes --- client/imports/lab/methods.ts | 5 +---- server/imports/api/lab.env.js | 18 +++++++++--------- server/imports/lab/methods.ts | 5 +---- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/client/imports/lab/methods.ts b/client/imports/lab/methods.ts index caad34d4..fcd09bbb 100644 --- a/client/imports/lab/methods.ts +++ b/client/imports/lab/methods.ts @@ -1,8 +1,5 @@ Meteor.methods({ - 'test': function(){ - return "I cri"; - }, - 'createLab': function(courseId : String ,labId : Number){ + 'prepareLab': function(courseId : String ,labId : Number){ return "here"; } }); diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index 7fa386cd..38d676de 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -23,7 +23,7 @@ var env = function(){ password: nconf.get('docker_port') } - this.docker = new dockerode(docker_settings); //TODO: nconf.get??? + this.docker = new dockerode(docker_settings); this.etcd = new etcd(etcd_address,etcd_auth); this.root_dom = nconf.get("root_domain"); @@ -100,7 +100,7 @@ env.prototype.init = function(opts){ var dck = this.docker; - //image defaults to alpine + //get default image var img = nconf.get('default_image'); var crtOpts = null var strOpts = null; @@ -116,7 +116,7 @@ env.prototype.init = function(opts){ //change final options according to opts input, if there is any underscore.extend(crtOptsf, crtOpts); - + var slf = this; return new Promise(function(resolve,reject){ @@ -186,14 +186,14 @@ env.prototype.init = function(opts){ else{ slf.vmList.labVm = slf.labVm; resolve(); - } + } }); - } + } }); - }); - } - }); - } + }); + } + }); + } }); } }); diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 5328b12e..20793f96 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,9 +1,6 @@ declare var Collections : any; Meteor.methods({ - 'test'(){ - return "hello"; - }, - 'createLab': function(courseId : String,labId : Number){ + 'prepareLab': function(courseId : String,labId : Number){ var course = Collections.courses.findOne({_id: courseId}).fetch(); //var t = require('../api/labExec.js'); return course.labs.find((l) => { return l._id == labId; }); From 6bac2e295a19189b93ff8d6f25f8e57812e2aaa1 Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 7 Jul 2016 13:49:25 -0400 Subject: [PATCH 05/49] fixed #82 --- server/imports/api/lab.exec.js | 87 ++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/server/imports/api/lab.exec.js b/server/imports/api/lab.exec.js index 1aa0c809..faf4a763 100644 --- a/server/imports/api/lab.exec.js +++ b/server/imports/api/lab.exec.js @@ -1,12 +1,10 @@ var _eval = require('eval'); -var mongo = require('mongodb'); -var mongoClient = mongo.MongoClient; -var url = "mongodb://tuxlab:cQPD9wte@ds025792.mlab.com:25792/tuxlab"; var labExec = function(){ - this.env = require('./env.js'); + this.env = require('./lab.env.js'); }; +//TODO: move to somewhere else labExec.prototype.check = function(str){ if(!str) { return false; } try { @@ -27,48 +25,85 @@ labExec.prototype.check = function(str){ (tux.newTask.toString() === tuxOrig.newTask.toString()); } +/* init: pulls labFile and initializes labExec object from it + */ labExec.prototype.init = function(user,courseId,labId){ var slf = this; this.env.setUser(user); - labMongo.importLab(courseId,labId,function(lab){ - if(!slf.check(lab.file)){ - console.log("labFile corrupt"); - } - else{ - slf.tuxlab = eval(lab.file); - console.log("success!"); - console.log(slf.tuxlab); - } - }); + var course = Collections.courses.find({_id: courseId}); + var lab_id = course.labs[labId]; + var lab = Collections.courses.find({_id: lab_id}); + slf.tuxlab = _eval(lab.labfile); + slf.tuxlab.taskNo = 0; + callback(null,slf.parseTasks()); } labExec.prototype.parseTasks = function(){ - return this.tuxlab.taskList.map(function(task){ return {title: task.title, - markdown: task.markdown, - }; }); + var slf = this; + return this.tuxlab.taskList.map(function(task,i){ + if(i <= slf.tuxlab.taskNo){ + return {title: task.title, markdown: task.markdown}; + } + return {title: task.title, markdown: null}; + }); } +/* start: runs setup and moves task header to first task + * runs callback(err,res) on err if there is an error, + * (null,parseTasks) no error + */ labExec.prototype.start = function(callback){ var slf = this; + this.tuxlab.taskNo = 1; this.tuxlab.setup(this.env) .then(function(){ slf.tuxlab.tasks(this.env); }) var tasks = this.tuxlab.tasks(this.env); - if(!this.tuxlab.currentTask.next) throw "Tasks not properly chained"; + if(!this.tuxlab.currentTask.next){ + TuxLog.log('labfile_error','labfile tasks not properly chained at start'); + callback("Internal error",null); + } this.tuxlab.currentTask = this.tuxlab.currentTask.next; - this.currentTask.sFn().then(function(){ callback(slf.parseTasks); }); + this.currentTask.sFn().then(function(){ callback(null,slf.parseTasks(0)); }); } +/* next: verifies that task is completed + * moves on to next task and runs callback(null,parseTasks) if completed + * runs callback(err,null) -err from verify- if not + */ labExec.prototype.next = function(callback){ var slf = this; - if(this.tuxlab.currentTask.isLast()) throw "cannot call next on last task"; - currentTask.vFn().then(function(){ slf.tuxlab.currentTask = slf.tuxlab.currentTask.next; - slf.tuxlab.currentTask.sFn().then(function(){ - callback(slf.tuxlab.currentTask);})}, - function(){ /*handle the error*/ }); + if(this.tuxlab.currentTask.isLast()){ + TuxLog.log("debug","trying to call nextTask on last task"); + callback("Internall error",null); + } + this.tuxlabcurrentTask.vFn().then(function(){ + slf.tuxlab.currentTask = slf.tuxlab.currentTask.next; + slf.tuxlab.currentTask.sFn() + .then(function(){ + slf.tuxLab.taskNo += 1; + callback(null,slf.parseTasks());}) + }, + function(err){ + callback(err,null); + }); } -labExec.prototype.end = function(){ -//same as next, will change after testing +/* end: verifies that last task is completed + * runs callback on (null,done) if verify runs correctly + * runs callback (err, null) if not + */ +labExec.prototype.end = function(callback){ + var slf = this; + if(!this.tuxlab.currentTask.isLast()){ + TuxLog.log("debug","trying to call end on a non-last task"); + callback("Internal error",null); //TODO: should we allow end on non-last tasks? @Derek + } + this.tuxlab.currentTask.vFn().then(function(){ + callback(null,"done"); + }, + function(){ + callback(err,null); + }); } module.exports = new labExec(); From 0498eb0d682247aba483143fac5c5349b2ca79c8 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 8 Jul 2016 10:57:02 -0400 Subject: [PATCH 06/49] isse #77 --- collections/checkLab.d.ts | 3 +++ collections/checkLab.js | 14 +++++++++++ collections/labs.ts | 25 ++++++++++++++++++- collections/tuxlab.js | 40 +++++++++++++++++++++++++++++++ server/imports/lab/methods.ts | 5 ++-- tests/example_data/badlabfile1.js | 33 +++++++++++++++++++++++++ tests/example_data/labfile1.js | 1 + tests/example_data/tuxlab.js | 40 +++++++++++++++++++++++++++++++ tests/tuxlab.db.js | 4 ++-- 9 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 collections/checkLab.d.ts create mode 100644 collections/checkLab.js create mode 100644 collections/tuxlab.js create mode 100644 tests/example_data/badlabfile1.js create mode 100644 tests/example_data/tuxlab.js diff --git a/collections/checkLab.d.ts b/collections/checkLab.d.ts new file mode 100644 index 00000000..8ac614d6 --- /dev/null +++ b/collections/checkLab.d.ts @@ -0,0 +1,3 @@ +declare module "validateLab" { + export function validateLab(str: string): boolean +} diff --git a/collections/checkLab.js b/collections/checkLab.js new file mode 100644 index 00000000..6aa8a472 --- /dev/null +++ b/collections/checkLab.js @@ -0,0 +1,14 @@ +"use strict"; +module.exports = function(str){ + + if(!str) { return false; } + var tux = eval(str); + //var s = tuxlab; + var tuxOrig = require('./tuxlab.js'); + return ((typeof tux != "undefined") && + (typeof tux.setup === 'function') && //check for instructor field types + (typeof tux.tasks === 'function') && + (tux.init.toString() === tuxOrig.init.toString()) && //check for unchanged + (tux.newTask.toString() === tuxOrig.newTask.toString())); + +} diff --git a/collections/labs.ts b/collections/labs.ts index f229464a..71bf4dc6 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -3,6 +3,9 @@ import { Meteor } from 'meteor/meteor'; import { Roles } from './users.ts'; +//import { validateLab } from './checkLab.ts'; +declare var validateLab : any; +import validateLab = require('./checkLab'); export const labs : any = new Mongo.Collection('labs'); /** @@ -78,10 +81,30 @@ labs.allow({ if(Meteor.isServer){ Meteor.startup(function(){ var LabValidator = function(userid, doc, fieldNames?, modifier?, options?){ - if (typeof fieldNames === "undefined" || fieldNames.includes('tasks') || fieldNames.includes('file')){ + if (typeof fieldNames === "undefined"){ + console.log("inserting"); + if(!(doc.course_id && doc.file && //check for lab fields + (Meteor.isServer || Roles.isInstructorFor(doc.course_id,userid))&& //check for instructor authorization + validateLab(doc.file))){ //check for labfile errors + return false; + } + //TODO @CEM: Validate Lab //TODO @CEM: Generate tasks array } + else if(fieldNames.includes('tasks') && !fieldNames.includes('file')){ + return false; + } + else if(fieldNames.includes('file')){ + if(!((Meteor.isServer || Roles.isInstructorFor(doc.course_id,userid)) && //check for instructor authorization + validateLab(modifier.$set.file))){ //check for labfile errors + return false; + } + else{ + if(modifier) {modifier.$set.updated = Date.now(); } + doc.updated = Date.now(); + } + } } labs.before.update(LabValidator); labs.before.insert(LabValidator); diff --git a/collections/tuxlab.js b/collections/tuxlab.js new file mode 100644 index 00000000..b213b025 --- /dev/null +++ b/collections/tuxlab.js @@ -0,0 +1,40 @@ +var tuxlab = function(){} + +tuxlab.prototype.init = function(){ + var slf = this; + var ts = { prnt: slf, + next: null, + nextTask: function(tsk){ + this.next = tsk; + this.prnt.taskList.push(tsk); + return tsk; + } + } + this.currentTask = ts; + return ts; +} + +tuxlab.prototype.currentTask = null; +tuxlab.prototype.taskList = []; +tuxlab.prototype.setup; +tuxlab.prototype.tasks; +tuxlab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ + var slf = this; + var ts = { prnt: slf, + setupFn: sFn, + verifyFn: vFn, + opts: opt, + markdown: mdown, + title: ttl, + next: null, + completed: false, + nextTask: function(tsk){ + this.next = tsk; + this.prnt.taskList.push(tsk); + return tsk; + }, + isLast: function(){ return this.next === null; } + } + return ts; +} +module.exports = new tuxlab(); diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 20793f96..9cf5af26 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,9 +1,10 @@ declare var Collections : any; Meteor.methods({ 'prepareLab': function(courseId : String,labId : Number){ - var course = Collections.courses.findOne({_id: courseId}).fetch(); + console.log("here"); + // var course = Collections.courses.findOne({_id: courseId}).fetch(); //var t = require('../api/labExec.js'); - return course.labs.find((l) => { return l._id == labId; }); + // return course.labs.find((l) => { return l._id == labId; }); } }); diff --git a/tests/example_data/badlabfile1.js b/tests/example_data/badlabfile1.js new file mode 100644 index 00000000..06c5f939 --- /dev/null +++ b/tests/example_data/badlabfile1.js @@ -0,0 +1,33 @@ +var tuxlab = require('./tuxlab.js'); + +tuxlab.setup = 5; +tuxlab.tasks = function(env){ + var s1 = function(){ + env.start() + .then(env.createVm({dockerodeCreateOptions: {name: "derek"}})) + .then(env.shell("labVm","cd ~./home/usr/derek")) + .then(function(sOut){ console.log("succ: "+sOut); }, + function(sOut,sErr,sDock){ throw sOut+sErr+sDock; }); + } + var v1 = function(){ + env.shell("labVm","pwd") + .then(function(sOut){ if(sOut === "/usr/home/derek") return true; else return false; }); + } + var s2 = function(){} + var v2 = function(){} + var s3 = function(){} + var v3 = function(){} + var s4 = function(){} + var v4 = function(){} + var task1 = tuxlab.newTask('TASK1','MD1',s1,v1) + var task2 = tuxlab.newTask('TASK2','MD2',s2,v2) + var task3 = tuxlab.newTask('TASK3','MD3',s3,v3) + var task4 = tuxlab.newTask('TASK4','MD4',s4,v4) + return tuxlab.init() + .nextTask(task1) + .nextTask(task2) + .nextTask(task3) + .nextTask(task4); +} +module.exports = tuxlab; +//export tuxlab diff --git a/tests/example_data/labfile1.js b/tests/example_data/labfile1.js index 5c2d4925..adda0e8f 100644 --- a/tests/example_data/labfile1.js +++ b/tests/example_data/labfile1.js @@ -38,3 +38,4 @@ tuxlab.tasks = function(env){ .nextTask(task4); } module.exports = tuxlab; +//export tuxlab diff --git a/tests/example_data/tuxlab.js b/tests/example_data/tuxlab.js new file mode 100644 index 00000000..0229ef60 --- /dev/null +++ b/tests/example_data/tuxlab.js @@ -0,0 +1,40 @@ +var tuxlab = function(){} +/* +tuxlab.prototype.init = function(){ + var slf = this; + var ts = { prnt: slf, + next: null, + nextTask: function(tsk){ + this.next = tsk; + this.prnt.taskList.push(tsk); + return tsk; + } + } + this.currentTask = ts; + return ts; +} +*/ +tuxlab.prototype.currentTask = null; +tuxlab.prototype.taskList = []; +tuxlab.prototype.setup; +tuxlab.prototype.tasks;/* +tuxlab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ + var slf = this; + var ts = { prnt: slf, + setupFn: sFn, + verifyFn: vFn, + opts: opt, + markdown: mdown, + title: ttl, + next: null, + completed: false, + nextTask: function(tsk){ + this.next = tsk; + this.prnt.taskList.push(tsk); + return tsk; + }, + isLast: function(){ return this.next === null; } + } + return ts; +}*/ +module.exports = new tuxlab(); diff --git a/tests/tuxlab.db.js b/tests/tuxlab.db.js index 194a9fc2..0b2ab430 100644 --- a/tests/tuxlab.db.js +++ b/tests/tuxlab.db.js @@ -92,7 +92,7 @@ describe('Example Database', function(){ }); // Validate that Records Exists - if('should have uploaded these records', function(){ +/* it('should have uploaded these records', function(){ return server.execute(function(course_id, lab_id){ var course = Collections.findOne(course_id).fetch(); @@ -106,6 +106,6 @@ describe('Example Database', function(){ }, [course_id, lab_id]); }); - +*/ }); From 097ff58a986ce68c5f7fbe8d6dd53dc633ee5dbf Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 8 Jul 2016 11:24:31 -0400 Subject: [PATCH 07/49] fixed tests --- client/tuxlab.ts | 98 ---------------------------------------------- tests/tuxlab.db.js | 8 ++-- 2 files changed, 4 insertions(+), 102 deletions(-) delete mode 100644 client/tuxlab.ts diff --git a/client/tuxlab.ts b/client/tuxlab.ts deleted file mode 100644 index 969636e9..00000000 --- a/client/tuxlab.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* TuxLab - TuxLab.ts */ - -// Meteor Imports - import { Meteor } from 'meteor/meteor'; - import { Mongo } from 'meteor/mongo'; - import 'reflect-metadata'; - import 'zone.js/dist/zone'; - -// Angular Imports - import { Component, ViewEncapsulation, provide } from '@angular/core'; - import { bootstrap } from 'angular2-meteor-auto-bootstrap'; - - import { APP_BASE_HREF } from '@angular/common'; - import { HTTP_PROVIDERS } from '@angular/http'; - import { RouterLink, ROUTER_PROVIDERS, ROUTER_DIRECTIVES, RouteConfig } from '@angular/router-deprecated'; - - import { InjectUser } from 'angular2-meteor-accounts-ui'; - -// Angular Material Imports - import { MATERIAL_PROVIDERS, MATERIAL_DIRECTIVES } from 'ng2-material'; - import { MeteorComponent } from 'angular2-meteor'; - import { MD_SIDENAV_DIRECTIVES } from '@angular2-material/sidenav'; - -// Toolbar - import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; - -// Icon - import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon' - -// UI Imports - import { Dashboard } from "./imports/ui/pages/dashboard/dashboard" - import { Login } from "./imports/ui/pages/account/login" - import { Account } from "./imports/ui/pages/account/account" - import { Err404 } from "./imports/ui/pages/error/404" - import { TaskView } from "./imports/ui/pages/lab/taskview"; - import { CourseView } from "./imports/ui/pages/course/course"; - import { LabView } from "./imports/ui/pages/course/lablist"; - import { GradeView } from "./imports/ui/pages/course/gradelist"; - import { Explore } from "./imports/ui/pages/explore/explore"; - import { Instructor } from "./imports/ui/pages/instructor/instructor"; - import { Terms } from "./imports/ui/pages/static/terms"; - import { Privacy } from "./imports/ui/pages/static/privacy"; - -// Define TuxLab Component -@Component({ - selector: 'tuxlab', - templateUrl: '/client/tuxlab.html', - directives: [ ROUTER_DIRECTIVES, - MATERIAL_DIRECTIVES, - MD_TOOLBAR_DIRECTIVES, - MD_ICON_DIRECTIVES, - MD_SIDENAV_DIRECTIVES, - RouterLink ], - viewProviders: [MdIconRegistry], - encapsulation: ViewEncapsulation.None -}) - -// Define TuxLab Routes -@RouteConfig([ - { path: '/', component: Dashboard }, - { path: '/login', component: Login }, - { path: '/lab', component: TaskView }, - { path: '/course', component: CourseView }, - { path: '/labs', component: LabView }, - { path: '/grades', component: GradeView }, - { path: '/explore', component: Explore }, - { path: '/instructor', component: Instructor }, - { path: '/terms', component: Terms }, - { path: '/privacy', component: Privacy }, -// { path: '/course/:courseid', as: 'CourseView', component: CourseView }, -// { path: '/course/:courseid/users', as: 'UserList', component: UserList }, -// { path: '/course/:courseid/user/:userid', as: 'UserView', component: UserView }, -// { path: '/course/:courseid/labs', as: 'LabList', component: LabList }, -// { path: '/course/:courseid/lab/:labid', as: 'LabView', component: LabView }, - { path: '/account/:userid', component: Account }, - { path: '/**', component: Err404 } -]) - -@InjectUser("user") -class TuxLab extends MeteorComponent { - user: Meteor.User; - constructor(mdIconRegistry: MdIconRegistry) { - super(); - // Create Icon Font - mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); - mdIconRegistry.setDefaultFontSetClass('tuxicon'); - } - tuxLogout() { - Meteor.logout(); - } -} - -bootstrap(TuxLab, [ - MATERIAL_PROVIDERS, - HTTP_PROVIDERS, - MdIconRegistry, - ROUTER_PROVIDERS, - provide(APP_BASE_HREF, { useValue: '/' })]); diff --git a/tests/tuxlab.db.js b/tests/tuxlab.db.js index 0b2ab430..b7acabee 100644 --- a/tests/tuxlab.db.js +++ b/tests/tuxlab.db.js @@ -92,20 +92,20 @@ describe('Example Database', function(){ }); // Validate that Records Exists -/* it('should have uploaded these records', function(){ + it('should have uploaded these records', function(){ return server.execute(function(course_id, lab_id){ - var course = Collections.findOne(course_id).fetch(); + var course = Collections.courses.findOne({_id: course_id}); // Check Lab Injection expect(course).to.have.property('labs'); expect(course.labs).to.include(lab_id); - var lab = Collections.findOne(lab_id).fetch(); + var lab = Collections.labs.findOne({_id: lab_id}); // Confirm LabFile verifications were run }, [course_id, lab_id]); }); -*/ + }); From 30ee6c21578b902a517f04198d5d87e0153e41d3 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 8 Jul 2016 11:54:39 -0400 Subject: [PATCH 08/49] fixed files --- client/tuxlab.ts | 98 ++++++++++++++++++++++++++++++++++++ tests/example_data/tuxlab.js | 40 --------------- 2 files changed, 98 insertions(+), 40 deletions(-) create mode 100644 client/tuxlab.ts delete mode 100644 tests/example_data/tuxlab.js diff --git a/client/tuxlab.ts b/client/tuxlab.ts new file mode 100644 index 00000000..969636e9 --- /dev/null +++ b/client/tuxlab.ts @@ -0,0 +1,98 @@ +/* TuxLab - TuxLab.ts */ + +// Meteor Imports + import { Meteor } from 'meteor/meteor'; + import { Mongo } from 'meteor/mongo'; + import 'reflect-metadata'; + import 'zone.js/dist/zone'; + +// Angular Imports + import { Component, ViewEncapsulation, provide } from '@angular/core'; + import { bootstrap } from 'angular2-meteor-auto-bootstrap'; + + import { APP_BASE_HREF } from '@angular/common'; + import { HTTP_PROVIDERS } from '@angular/http'; + import { RouterLink, ROUTER_PROVIDERS, ROUTER_DIRECTIVES, RouteConfig } from '@angular/router-deprecated'; + + import { InjectUser } from 'angular2-meteor-accounts-ui'; + +// Angular Material Imports + import { MATERIAL_PROVIDERS, MATERIAL_DIRECTIVES } from 'ng2-material'; + import { MeteorComponent } from 'angular2-meteor'; + import { MD_SIDENAV_DIRECTIVES } from '@angular2-material/sidenav'; + +// Toolbar + import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; + +// Icon + import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon' + +// UI Imports + import { Dashboard } from "./imports/ui/pages/dashboard/dashboard" + import { Login } from "./imports/ui/pages/account/login" + import { Account } from "./imports/ui/pages/account/account" + import { Err404 } from "./imports/ui/pages/error/404" + import { TaskView } from "./imports/ui/pages/lab/taskview"; + import { CourseView } from "./imports/ui/pages/course/course"; + import { LabView } from "./imports/ui/pages/course/lablist"; + import { GradeView } from "./imports/ui/pages/course/gradelist"; + import { Explore } from "./imports/ui/pages/explore/explore"; + import { Instructor } from "./imports/ui/pages/instructor/instructor"; + import { Terms } from "./imports/ui/pages/static/terms"; + import { Privacy } from "./imports/ui/pages/static/privacy"; + +// Define TuxLab Component +@Component({ + selector: 'tuxlab', + templateUrl: '/client/tuxlab.html', + directives: [ ROUTER_DIRECTIVES, + MATERIAL_DIRECTIVES, + MD_TOOLBAR_DIRECTIVES, + MD_ICON_DIRECTIVES, + MD_SIDENAV_DIRECTIVES, + RouterLink ], + viewProviders: [MdIconRegistry], + encapsulation: ViewEncapsulation.None +}) + +// Define TuxLab Routes +@RouteConfig([ + { path: '/', component: Dashboard }, + { path: '/login', component: Login }, + { path: '/lab', component: TaskView }, + { path: '/course', component: CourseView }, + { path: '/labs', component: LabView }, + { path: '/grades', component: GradeView }, + { path: '/explore', component: Explore }, + { path: '/instructor', component: Instructor }, + { path: '/terms', component: Terms }, + { path: '/privacy', component: Privacy }, +// { path: '/course/:courseid', as: 'CourseView', component: CourseView }, +// { path: '/course/:courseid/users', as: 'UserList', component: UserList }, +// { path: '/course/:courseid/user/:userid', as: 'UserView', component: UserView }, +// { path: '/course/:courseid/labs', as: 'LabList', component: LabList }, +// { path: '/course/:courseid/lab/:labid', as: 'LabView', component: LabView }, + { path: '/account/:userid', component: Account }, + { path: '/**', component: Err404 } +]) + +@InjectUser("user") +class TuxLab extends MeteorComponent { + user: Meteor.User; + constructor(mdIconRegistry: MdIconRegistry) { + super(); + // Create Icon Font + mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); + mdIconRegistry.setDefaultFontSetClass('tuxicon'); + } + tuxLogout() { + Meteor.logout(); + } +} + +bootstrap(TuxLab, [ + MATERIAL_PROVIDERS, + HTTP_PROVIDERS, + MdIconRegistry, + ROUTER_PROVIDERS, + provide(APP_BASE_HREF, { useValue: '/' })]); diff --git a/tests/example_data/tuxlab.js b/tests/example_data/tuxlab.js deleted file mode 100644 index 0229ef60..00000000 --- a/tests/example_data/tuxlab.js +++ /dev/null @@ -1,40 +0,0 @@ -var tuxlab = function(){} -/* -tuxlab.prototype.init = function(){ - var slf = this; - var ts = { prnt: slf, - next: null, - nextTask: function(tsk){ - this.next = tsk; - this.prnt.taskList.push(tsk); - return tsk; - } - } - this.currentTask = ts; - return ts; -} -*/ -tuxlab.prototype.currentTask = null; -tuxlab.prototype.taskList = []; -tuxlab.prototype.setup; -tuxlab.prototype.tasks;/* -tuxlab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ - var slf = this; - var ts = { prnt: slf, - setupFn: sFn, - verifyFn: vFn, - opts: opt, - markdown: mdown, - title: ttl, - next: null, - completed: false, - nextTask: function(tsk){ - this.next = tsk; - this.prnt.taskList.push(tsk); - return tsk; - }, - isLast: function(){ return this.next === null; } - } - return ts; -}*/ -module.exports = new tuxlab(); From e156b44a5203983e25bedd5832b0841a953dc3fd Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 8 Jul 2016 12:40:26 -0400 Subject: [PATCH 09/49] fixed tests master --- collections/checkLab.js | 14 ++++++++++++++ collections/labs.ts | 24 +++++++++++++++++++++++- collections/tuxlab.js | 40 ++++++++++++++++++++++++++++++++++++++++ tests/tuxlab.db.js | 7 +++++-- 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 collections/checkLab.js create mode 100644 collections/tuxlab.js diff --git a/collections/checkLab.js b/collections/checkLab.js new file mode 100644 index 00000000..6aa8a472 --- /dev/null +++ b/collections/checkLab.js @@ -0,0 +1,14 @@ +"use strict"; +module.exports = function(str){ + + if(!str) { return false; } + var tux = eval(str); + //var s = tuxlab; + var tuxOrig = require('./tuxlab.js'); + return ((typeof tux != "undefined") && + (typeof tux.setup === 'function') && //check for instructor field types + (typeof tux.tasks === 'function') && + (tux.init.toString() === tuxOrig.init.toString()) && //check for unchanged + (tux.newTask.toString() === tuxOrig.newTask.toString())); + +} diff --git a/collections/labs.ts b/collections/labs.ts index ea8ac456..9f1568ea 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -3,6 +3,8 @@ import { Meteor } from 'meteor/meteor'; import { Roles } from './users.ts'; +declare var validateLab : any; +import validateLab = require('./checkLab'); export const labs : any = new Mongo.Collection('labs'); /** @@ -82,10 +84,30 @@ labs.allow({ if(Meteor.isServer){ Meteor.startup(function(){ var LabValidator = function(userid, doc, fieldNames?, modifier?, options?){ - if (typeof fieldNames === "undefined" || fieldNames.includes('tasks') || fieldNames.includes('file')){ + if (typeof fieldNames === "undefined"){ + console.log("inserting"); + if(!(doc.course_id && doc.file && //check for lab fields + (Meteor.isServer || Roles.isInstructorFor(doc.course_id,userid))&& //check for instructor authorization + validateLab(doc.file))){ //check for labfile errors + return false; + } + //TODO @CEM: Validate Lab //TODO @CEM: Generate tasks array } + else if(fieldNames.includes('tasks') && !fieldNames.includes('file')){ + return false; + } + else if(fieldNames.includes('file')){ + if(!((Meteor.isServer || Roles.isInstructorFor(doc.course_id,userid)) && //check for instructor authorization + validateLab(modifier.$set.file))){ //check for labfile errors + return false; + } + else{ + if(modifier) {modifier.$set.updated = Date.now(); } + doc.updated = Date.now(); + } + } } labs.before.update(LabValidator); labs.before.insert(LabValidator); diff --git a/collections/tuxlab.js b/collections/tuxlab.js new file mode 100644 index 00000000..b213b025 --- /dev/null +++ b/collections/tuxlab.js @@ -0,0 +1,40 @@ +var tuxlab = function(){} + +tuxlab.prototype.init = function(){ + var slf = this; + var ts = { prnt: slf, + next: null, + nextTask: function(tsk){ + this.next = tsk; + this.prnt.taskList.push(tsk); + return tsk; + } + } + this.currentTask = ts; + return ts; +} + +tuxlab.prototype.currentTask = null; +tuxlab.prototype.taskList = []; +tuxlab.prototype.setup; +tuxlab.prototype.tasks; +tuxlab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ + var slf = this; + var ts = { prnt: slf, + setupFn: sFn, + verifyFn: vFn, + opts: opt, + markdown: mdown, + title: ttl, + next: null, + completed: false, + nextTask: function(tsk){ + this.next = tsk; + this.prnt.taskList.push(tsk); + return tsk; + }, + isLast: function(){ return this.next === null; } + } + return ts; +} +module.exports = new tuxlab(); diff --git a/tests/tuxlab.db.js b/tests/tuxlab.db.js index b59ab94e..d7a5f551 100644 --- a/tests/tuxlab.db.js +++ b/tests/tuxlab.db.js @@ -52,17 +52,20 @@ describe('Database Schema', function(){ return server.promise(function(resolve, reject, labfile, course_id){ var example_lab = { + _id : "574467bc11091623418a429d", course_id : course_id, lab_name: "Getting Started with Git", file: labfile, tasks: [ { _id: 1, + updated: 1467995862937, name: "Git Clone", md: "##################" }, { _id: 2, + updated: 1467995862937, name: "Git Pull", md: "##################" } @@ -85,13 +88,13 @@ describe('Database Schema', function(){ // Validate that Records Exists it('should be accepted by database', function(){ return server.execute(function(course_id, lab_id){ - var course = Collections.courses.findOne(course_id).fetch(); + var course = Collections.courses.findOne(course_id); // Check Lab Injection expect(course).to.have.property('labs'); expect(course.labs).to.include(lab_id); - var lab = Collections.findOne(lab_id).fetch(); + var lab = Collections.labs.findOne(lab_id); // Confirm LabFile verifications were run From e9052be29e99dfcd9f5977c347aef1fcc7bb9f17 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 8 Jul 2016 13:10:52 -0400 Subject: [PATCH 10/49] fixed comment --- tests/example_data/labfile1.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/example_data/labfile1.js b/tests/example_data/labfile1.js index adda0e8f..ca8d39b0 100644 --- a/tests/example_data/labfile1.js +++ b/tests/example_data/labfile1.js @@ -37,5 +37,5 @@ tuxlab.tasks = function(env){ .nextTask(task3) .nextTask(task4); } +//export modified tuxlab module.exports = tuxlab; -//export tuxlab From 528fb7d10fff19d1b3abb8ff0c1995055cd81402 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 8 Jul 2016 13:26:18 -0400 Subject: [PATCH 11/49] moved validator --- collections/labs.ts | 2 +- .../imports/lab}/checkLab.d.ts | 0 .../imports/lab}/checkLab.js | 0 server/imports/lab/tuxlab.js | 40 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) rename {collections => server/imports/lab}/checkLab.d.ts (100%) rename {collections => server/imports/lab}/checkLab.js (100%) create mode 100644 server/imports/lab/tuxlab.js diff --git a/collections/labs.ts b/collections/labs.ts index 5aa0b9d5..9b747698 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -4,7 +4,7 @@ import { Meteor } from 'meteor/meteor'; import { Roles } from './users.ts'; declare var validateLab : any; -import validateLab = require('./checkLab'); +import validateLab = require('../server/imports/lab/checkLab'); export const labs : any = new Mongo.Collection('labs'); /** diff --git a/collections/checkLab.d.ts b/server/imports/lab/checkLab.d.ts similarity index 100% rename from collections/checkLab.d.ts rename to server/imports/lab/checkLab.d.ts diff --git a/collections/checkLab.js b/server/imports/lab/checkLab.js similarity index 100% rename from collections/checkLab.js rename to server/imports/lab/checkLab.js diff --git a/server/imports/lab/tuxlab.js b/server/imports/lab/tuxlab.js new file mode 100644 index 00000000..b213b025 --- /dev/null +++ b/server/imports/lab/tuxlab.js @@ -0,0 +1,40 @@ +var tuxlab = function(){} + +tuxlab.prototype.init = function(){ + var slf = this; + var ts = { prnt: slf, + next: null, + nextTask: function(tsk){ + this.next = tsk; + this.prnt.taskList.push(tsk); + return tsk; + } + } + this.currentTask = ts; + return ts; +} + +tuxlab.prototype.currentTask = null; +tuxlab.prototype.taskList = []; +tuxlab.prototype.setup; +tuxlab.prototype.tasks; +tuxlab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ + var slf = this; + var ts = { prnt: slf, + setupFn: sFn, + verifyFn: vFn, + opts: opt, + markdown: mdown, + title: ttl, + next: null, + completed: false, + nextTask: function(tsk){ + this.next = tsk; + this.prnt.taskList.push(tsk); + return tsk; + }, + isLast: function(){ return this.next === null; } + } + return ts; +} +module.exports = new tuxlab(); From e9f46e2e08ada945dde9f738ca43e53e795a0db1 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 8 Jul 2016 13:28:43 -0400 Subject: [PATCH 12/49] removed duplicate file --- collections/tuxlab.js | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 collections/tuxlab.js diff --git a/collections/tuxlab.js b/collections/tuxlab.js deleted file mode 100644 index b213b025..00000000 --- a/collections/tuxlab.js +++ /dev/null @@ -1,40 +0,0 @@ -var tuxlab = function(){} - -tuxlab.prototype.init = function(){ - var slf = this; - var ts = { prnt: slf, - next: null, - nextTask: function(tsk){ - this.next = tsk; - this.prnt.taskList.push(tsk); - return tsk; - } - } - this.currentTask = ts; - return ts; -} - -tuxlab.prototype.currentTask = null; -tuxlab.prototype.taskList = []; -tuxlab.prototype.setup; -tuxlab.prototype.tasks; -tuxlab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ - var slf = this; - var ts = { prnt: slf, - setupFn: sFn, - verifyFn: vFn, - opts: opt, - markdown: mdown, - title: ttl, - next: null, - completed: false, - nextTask: function(tsk){ - this.next = tsk; - this.prnt.taskList.push(tsk); - return tsk; - }, - isLast: function(){ return this.next === null; } - } - return ts; -} -module.exports = new tuxlab(); From a51100661c3852f9126c6945b6207e3b00eccfb0 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 8 Jul 2016 16:30:25 -0400 Subject: [PATCH 13/49] fixed tests, removed duplicate underscore, publish --- collections/labs.ts | 12 +++++++++++- server/imports/api/lab.env.js | 12 +++++------- tests/.tuxlab.db.js.swp | Bin 0 -> 12288 bytes tests/tuxlab.db.js | 1 - 4 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 tests/.tuxlab.db.js.swp diff --git a/collections/labs.ts b/collections/labs.ts index 9b747698..1aa1e73c 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -4,7 +4,10 @@ import { Meteor } from 'meteor/meteor'; import { Roles } from './users.ts'; declare var validateLab : any; -import validateLab = require('../server/imports/lab/checkLab'); +declare var _ : any; + +var _ = require('underscore'); +var validateLab = require('../server/imports/lab/checkLab'); export const labs : any = new Mongo.Collection('labs'); /** @@ -124,5 +127,12 @@ labs.allow({ } }); }); + Meteor.publish('user-labs',function(){ + this.autorun(function(computation){ + let roles = ((Meteor.users.findOne(this.userId))).roles; + let courses = roles.student.map((a) =>{return a[0]}); + return (courses.map(function(courseId){return {course: courseId, labs: ((Collections.courses.findOne(courseId)).labs)}})); + }); + }); }); } diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index 38d676de..e46d6535 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -1,9 +1,7 @@ // Import Dockerode var dockerode = require('dockerode'); - // Import other libraries var async = require('async'); -var underscore = require('underscore'); var etcd = require('node-etcd'); var nconf = require('nconf'); @@ -115,7 +113,7 @@ env.prototype.init = function(opts){ var crtOptsf = {Image: img,CMD: ['/bin/sh'], name: this.labVm} //change final options according to opts input, if there is any - underscore.extend(crtOptsf, crtOpts); + _.extend(crtOptsf, crtOpts); var slf = this; return new Promise(function(resolve,reject){ @@ -229,7 +227,7 @@ env.prototype.createVm = function(opts) { var crtOptsf = {Image:img,CMD:['/bin/sh']} //extend the final options with the supplied options - underscore.extend(crtOptsf,crtOpt); + _.extend(crtOptsf,crtOpt); crtOptsf.name = cName; //this.vmList.push({name: crtOpt.name,id:cName}); //clone this into slf to use in the promise @@ -287,7 +285,7 @@ env.prototype.removeVm = function (vmName,opts) { return new Promise(function(resolve,reject){ //check if container initialized - if(!underscore.has(this.vmList,vmName)){ + if(!_.has(this.vmList,vmName)){ TuxLog.log('labfile_error',"trying to delete non-existing vm"); reject("Internal error"); } @@ -308,7 +306,7 @@ env.prototype.updateVm = function(vmName, opts) { var slf = this; return function(){ return new Promise(function(resolve,reject){ - if(!underscore.has(slf.vmList,vmName)){ + if(!_.has(slf.vmList,vmName)){ TuxLog.log('labfile_error','trying to update non-existing vm'); reject("Internal error"); } @@ -331,7 +329,7 @@ env.prototype.shell = function(vmName,command,opts) { var slf = this; return function(){ return new Promise(function(resolve,reject){ - if(!underscore.has(slf.vmList,vmName)){ + if(!_.has(slf.vmList,vmName)){ TuxLog.log('labfile_error','trying to run shell on non-existing vm'); reject("Internal error"); } diff --git a/tests/.tuxlab.db.js.swp b/tests/.tuxlab.db.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..0adba5b4a918041c5d029795dde79eec2c998530 GIT binary patch literal 12288 zcmeI2O^6&t6vr!Bj7Ciq1wle$WrNJ@GTW2c-RxITh`Wgf5)!kUcvzR%)BVQnq^EnV z?%tgxU!a#Dh+;%geZ`%y;oJsc76Miz5C^;F)UDS7vkLIGmo6xe@T2C31Lx_Yga93H_&bctF}9hhSe$G zikjqwLDi$hnW$Y2qqb|-2h3Kh8d8Azq{6W4#7ID`4FP3Me1`{S~v>pT5be`y7@ z0$KsBfL1^&pcT*xXa%$aS^=$qRzNH8A5_4!g*e+IMEeFfkN^K?fB*k>n-K4Si{LHr z26zgb0h3@8SPRyGD;tIQ2)qt1fG5Em7y$+t0QZ7>z!uO0e%c_!hv0b-ff=w7T)tI^ zFTrQvQ*ah6g2%uS@DQkh64(rSz?EBs_#S)%z6O`T``|h7Ea(S);M<$=44en2zyUA@ zN?;SX5&W=Th)=+q;3e=3SOSlN`@!8{1Ly(2-Xz3T@Bw%mya1jCCjo(3@G#g4HiC6P zfZuNv;wx|w1Yit|g1f+X>x6g@ybDf)LtqQo3|BSc#_lBJT*SnfL^3U*g)o|tCCQYN4HuE<%-k5oWM z9lIj&HWt3;cx;)MYE@49Uc*sMxzDWcaa@uMq@0FhnLKnL7fF#+k(c(Nc8jdAjHy}2 zNtI#KXrNPHpAq^-os3XL#6ECYFcl9f@52zTi*9VtKuv%?o_)Y0?hl`qyOa$PdmcBB zjXR#@Ms}e~G6;Vz>k&7eHy6lgDZd3Vm&zp`vlMHSb>eyR9C+3c{aE5%rVM+YDA(nD zQrYo8mp3)8D2$XRv4&95pf*`iNacJX^XA!VU}dFr!g48?_aoPqb&{rKQ7a_;yd-Ti zH0x$SUBMtF+&^Nv4xWicOo`sJmM%dC>zfU=J0DzbVh6|vxDQYv>2GBo0f ztj9GmO^4|WH&+53b*tN!R!2 zy1l6t2km$hn!)j4LeA#yb4*Nd_Qt`HS91tuf>0Pb-s5sQG!=*Iq7%+bs05cVxwz!v zE+;zS)p-ng@Su0c=rAO#TeaHu@!H7X&~Resg;hrYCyp;qHe`F#2@1)U z#$+Xpwm9XwLOlzYbf@B{u&(Hd$Whps8`v}qMW($652lwqt6VbDmsvA^I76$cOf|gN zicIZ|!p2xHZ$s0ef)>PFW#r%0n&VT68F4et(@K+ zwF?;zH~wY0oVXbnUFn=u7sU9BjAq>stewP$EgU>n=&LL`XZ$8k9h{_|na7dLf-s9< z7FHfqCQc^Hbmd-~%s}F_M$cvo8@Iw4&POwEsVi8CnsrhL;M$IX+E6WTPz={(R(~^M z<8UY(4q4cw3a%JA$+JHVp2_%7?T#PB8JEuHSlD}KaZ*!z4r$QzvB96{oB$B2%yW$! z;Inwj$F8$Y#P1Zjg!tX%y2TdBKD|7JuQ@Nf6~OUmxny=Lt2XZPsG1)vjmz=~{ zfF^u^!^p+X#Vc!^Ue&q;v-f~>>tw|p8T?(Y>+35w55Bm5RjIRi>(S6t? Klsp_zZ1xYYL~h0a literal 0 HcmV?d00001 diff --git a/tests/tuxlab.db.js b/tests/tuxlab.db.js index d7a5f551..40bb5b21 100644 --- a/tests/tuxlab.db.js +++ b/tests/tuxlab.db.js @@ -95,7 +95,6 @@ describe('Database Schema', function(){ expect(course.labs).to.include(lab_id); var lab = Collections.labs.findOne(lab_id); - // Confirm LabFile verifications were run }, [course_id, lab_id]); From 7cca5d34afd0ac754470bbe724b722e49a8bac7c Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 14 Jul 2016 10:21:09 -0400 Subject: [PATCH 14/49] changes --- collections/labs.ts | 5 ++++- server/imports/api/lab.exec.d.ts | 8 ++++++++ server/imports/api/lab.exec.js | 1 + server/imports/lab/checkLab.js | 21 ++++++++++----------- server/imports/lab/methods.ts | 4 ++-- 5 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 server/imports/api/lab.exec.d.ts diff --git a/collections/labs.ts b/collections/labs.ts index ad734826..77ee3d75 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -6,8 +6,9 @@ import { Roles } from './users.ts'; declare var validateLab : any; declare var _ : any; + var _ = require('underscore'); -var validateLab = require('../server/imports/lab/checkLab'); + export const labs : any = new Mongo.Collection('labs'); /** @@ -96,6 +97,8 @@ labs.allow({ /* LAB VALIDATOR */ if(Meteor.isServer){ + var validateLab = require('../server/imports/lab/checkLab.js'); + Meteor.startup(function(){ var LabValidator = function(userid, doc, fieldNames?, modifier?, options?){ if (typeof fieldNames === "undefined"){ diff --git a/server/imports/api/lab.exec.d.ts b/server/imports/api/lab.exec.d.ts new file mode 100644 index 00000000..656109a4 --- /dev/null +++ b/server/imports/api/lab.exec.d.ts @@ -0,0 +1,8 @@ +declare module 'labExec' { + export function labExec() : any + export function init(user: number, courseId: string, labId: number) : any + export function parseTasks() : any + export function start(callback : any) : any + export function next(callback : any) : any + export function end(callback : any) : any +} diff --git a/server/imports/api/lab.exec.js b/server/imports/api/lab.exec.js index faf4a763..ab71c3ad 100644 --- a/server/imports/api/lab.exec.js +++ b/server/imports/api/lab.exec.js @@ -1,3 +1,4 @@ +/// var _eval = require('eval'); var labExec = function(){ diff --git a/server/imports/lab/checkLab.js b/server/imports/lab/checkLab.js index 6aa8a472..3b638493 100644 --- a/server/imports/lab/checkLab.js +++ b/server/imports/lab/checkLab.js @@ -1,14 +1,13 @@ "use strict"; +/// module.exports = function(str){ - - if(!str) { return false; } - var tux = eval(str); - //var s = tuxlab; - var tuxOrig = require('./tuxlab.js'); - return ((typeof tux != "undefined") && - (typeof tux.setup === 'function') && //check for instructor field types - (typeof tux.tasks === 'function') && - (tux.init.toString() === tuxOrig.init.toString()) && //check for unchanged - (tux.newTask.toString() === tuxOrig.newTask.toString())); - + if(!str) { return false; } //check for file import + var tux = eval(str); + //var s = tuxlab; + var tuxOrig = require('./tuxlab.js'); + return ((typeof tux != "undefined") && + (typeof tux.setup === 'function') && //check for instructor field types + (typeof tux.tasks === 'function') && + (tux.init.toString() === tuxOrig.init.toString()) && //check for unchanged + (tux.newTask.toString() === tuxOrig.newTask.toString())); } diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 9cf5af26..8c952b5f 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -2,8 +2,8 @@ declare var Collections : any; Meteor.methods({ 'prepareLab': function(courseId : String,labId : Number){ console.log("here"); - // var course = Collections.courses.findOne({_id: courseId}).fetch(); - //var t = require('../api/labExec.js'); + var course = Collections.courses.findOne({_id: courseId}).fetch(); + var t = require('../api/labExec.js'); // return course.labs.find((l) => { return l._id == labId; }); } }); From d6c8c4a36c4b153f3900159b523fdfa2ae2f27bf Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 14 Jul 2016 10:38:35 -0400 Subject: [PATCH 15/49] fixed methods.ts import --- package.json | 5 +---- server/imports/api/lab.exec.js | 20 -------------------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/package.json b/package.json index eee8c4b7..d6855c46 100644 --- a/package.json +++ b/package.json @@ -48,11 +48,8 @@ "responsive-directives-angular2": "^0.3.0", "rxjs": "5.0.0-beta.6", "simplemde": "^1.11.2", - "winston": "2.2.0", -<<<<<<< HEAD + "winston": "^2.2.0", "winston-mongodb": "^1.6.0", -======= ->>>>>>> 942274e6e6c4010030727c43ce592507d6ef86f1 "zone.js": "^0.6.12" }, "devDependencies": { diff --git a/server/imports/api/lab.exec.js b/server/imports/api/lab.exec.js index 93d6a0d1..05e82317 100644 --- a/server/imports/api/lab.exec.js +++ b/server/imports/api/lab.exec.js @@ -5,26 +5,6 @@ var labExec = function(){ this.env = require('./lab.env.js'); }; -labExec.prototype.check = function(str){ - if(!str) { return false; } - try { - var tux = eval(str); - } - catch(e) { - console.log("compile error: "+e); - return false; - } - var tuxOrig = require('./tuxlab.js'); - return tux.setup && - tux.tasks && - tux.init && - tux.newTask && - (typeof tux.setup === 'function') && - (typeof tux.tasks === 'function') && - (tux.init.toString() === tuxOrig.init.toString()) && - (tux.newTask.toString() === tuxOrig.newTask.toString()); -} - /* init: pulls labFile and initializes labExec object from it */ labExec.prototype.init = function(user,labId,callback){ From 3db2e47b114dd67c3cb5319d1b9a2be34c616e11 Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 14 Jul 2016 11:07:36 -0400 Subject: [PATCH 16/49] fixed issues w methods --- server/imports/api/lab.exec.d.ts | 19 +++-- server/imports/api/lab.exec.js | 3 + server/imports/api/labExec.d.ts | 3 + server/imports/api/labExec.js | 125 +++++++++++++++++++++++++++++++ server/imports/lab/methods.ts | 6 +- 5 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 server/imports/api/labExec.d.ts create mode 100644 server/imports/api/labExec.js diff --git a/server/imports/api/lab.exec.d.ts b/server/imports/api/lab.exec.d.ts index 656109a4..5fbac7a5 100644 --- a/server/imports/api/lab.exec.d.ts +++ b/server/imports/api/lab.exec.d.ts @@ -1,8 +1,13 @@ -declare module 'labExec' { - export function labExec() : any - export function init(user: number, courseId: string, labId: number) : any - export function parseTasks() : any - export function start(callback : any) : any - export function next(callback : any) : any - export function end(callback : any) : any +namespace lab_exec { + interface labExec{ + var env : any; + var tuxlab : any; + function init(user : string, labId : number, callback : any) + function parseTasks() : any + function start(callback : any) : any + function next(callback : any) : any + function end(callback : any) : any + + } + function labExec() : any } diff --git a/server/imports/api/lab.exec.js b/server/imports/api/lab.exec.js index 05e82317..a00d8c40 100644 --- a/server/imports/api/lab.exec.js +++ b/server/imports/api/lab.exec.js @@ -5,6 +5,9 @@ var labExec = function(){ this.env = require('./lab.env.js'); }; + +labExec.prototype.env = null; +labExec.prototype.tuxlab = null; /* init: pulls labFile and initializes labExec object from it */ labExec.prototype.init = function(user,labId,callback){ diff --git a/server/imports/api/labExec.d.ts b/server/imports/api/labExec.d.ts new file mode 100644 index 00000000..edfe35b2 --- /dev/null +++ b/server/imports/api/labExec.d.ts @@ -0,0 +1,3 @@ +declare module 'labExec'{ + function labExec() : any +} diff --git a/server/imports/api/labExec.js b/server/imports/api/labExec.js new file mode 100644 index 00000000..05e82317 --- /dev/null +++ b/server/imports/api/labExec.js @@ -0,0 +1,125 @@ +/// +var _eval = require('eval'); + +var labExec = function(){ + this.env = require('./lab.env.js'); +}; + +/* init: pulls labFile and initializes labExec object from it + */ +labExec.prototype.init = function(user,labId,callback){ + var slf = this; + this.env.setUser(user); + + // Get Metadata from Database + slf.lab = Collections.labs.findOne({_id: lab_id}, {fields: {'file' : 0}}).fetch(); + if(lab.length < 0){ + callback(new Error("Lab Not Found.", null)); + } + else{ + + // Get Course Metadata + slf.course = Collections.courses.findOne({_id: lab.course_id}, {fields: {'labs' : 1 }}).fetch(); + + // Format LabFile Cache URL + var labfile_id = labId + "#" + lab.updated; + + // Check Cache for LabFile Object + LabCache.get(labfile_id, function(err, value){ + if(err){ + callback("TuxLab Exec Error.", null); + } + else if(typeof value === "undefined"){ + // Get LabFile from Database + var labfile_data = Collections.labs.findOne({_id: lab_id}, {fields : {'field' : 0}}).fetch(); + slf.tuxlab = _eval(lab.labfile); + + // Cache LabFile + LabCache.set(labfile_id, slf.tuxlab, function(err, success){ + if(err || !success){ + TuxLog.log('warn', err); + } + }); + + slf.tuxlab.taskNo = 0; + callback(null, lab.tasks); + } + else{ + // Get LabFile from Cache + slf.tuxlab.taskNo = 0; + slf.tuxlab = value; + callback(null, lab.tasks); + } + }); + } +} + +labExec.prototype.parseTasks = function(){ + var slf = this; + return this.tuxlab.taskList.map(function(task,i){ + if(i <= slf.tuxlab.taskNo){ + return {title: task.title, markdown: task.markdown}; + } + return {title: task.title, markdown: null}; + }); +} + +/* start: runs setup and moves task header to first task + * runs callback(err,res) on err if there is an error, + * (null,parseTasks) no error + */ +labExec.prototype.start = function(callback){ + var slf = this; + this.tuxlab.taskNo = 1; + this.tuxlab.setup(this.env) + .then(function(){ slf.tuxlab.tasks(this.env); }) + var tasks = this.tuxlab.tasks(this.env); + if(!this.tuxlab.currentTask.next){ + TuxLog.log('labfile_error','labfile tasks not properly chained at start'); + callback("Internal error",null); + } + this.tuxlab.currentTask = this.tuxlab.currentTask.next; + this.currentTask.sFn().then(function(){ callback(null,slf.parseTasks(0)); }); +} + +/* next: verifies that task is completed + * moves on to next task and runs callback(null,parseTasks) if completed + * runs callback(err,null) -err from verify- if not + */ +labExec.prototype.next = function(callback){ + var slf = this; + if(this.tuxlab.currentTask.isLast()){ + TuxLog.log("debug","trying to call nextTask on last task"); + callback("Internal error",null); + } + this.tuxlabcurrentTask.vFn().then(function(){ + slf.tuxlab.currentTask = slf.tuxlab.currentTask.next; + slf.tuxlab.currentTask.sFn() + .then(function(){ + slf.tuxLab.taskNo += 1; + callback(null,slf.parseTasks());}) + }, + function(err){ + callback(err,null); + }); +} + +/* end: verifies that last task is completed + * runs callback on (null,done) if verify runs correctly + * runs callback (err, null) if not + */ +labExec.prototype.end = function(callback){ + var slf = this; + if(!this.tuxlab.currentTask.isLast()){ + TuxLog.log("debug","trying to call end on a non-last task"); + callback("Internal error",null); //TODO: should we allow end on non-last tasks? @Derek + } + this.tuxlab.currentTask.vFn().then(function(){ + callback(null,"done"); + }, + function(){ + callback(err,null); + }); +} + +module.exports = new labExec(); diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 8c952b5f..70757869 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,10 +1,10 @@ declare var Collections : any; Meteor.methods({ - 'prepareLab': function(courseId : String,labId : Number){ + 'prepareLab': function(labId : number){ console.log("here"); - var course = Collections.courses.findOne({_id: courseId}).fetch(); var t = require('../api/labExec.js'); - // return course.labs.find((l) => { return l._id == labId; }); + t.init(Meteor.userId(),labId,console.log); + } }); From 719224f2d42637cf324d559d5435e01e8e4b7ba6 Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 14 Jul 2016 15:01:48 -0400 Subject: [PATCH 17/49] fixes --- client/imports/lab/methods.ts | 3 +++ server/imports/lab/methods.ts | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/client/imports/lab/methods.ts b/client/imports/lab/methods.ts index fcd09bbb..af4caace 100644 --- a/client/imports/lab/methods.ts +++ b/client/imports/lab/methods.ts @@ -1,6 +1,9 @@ Meteor.methods({ 'prepareLab': function(courseId : String ,labId : Number){ return "here"; + }, + 'trLab': function(labId: number) : number{ + return 3; } }); diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 70757869..3a7a9180 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,10 +1,19 @@ declare var Collections : any; Meteor.methods({ - 'prepareLab': function(labId : number){ + /**prepareLab: prepares a labExec object for the current user + * takes the id of the lab and a callback as parameter + * callback: (err,parseTasks,labExec) + */ + 'prepareLab': function(labId : number,callback : any){ console.log("here"); - var t = require('../api/labExec.js'); - t.init(Meteor.userId(),labId,console.log); - + var lab = require('../api/labExec.js'); + lab.init(Meteor.userId(),labId,function(err,parsed){ + callback(err,parsed,lab); + }); + }, + 'tyLab': function(labId : number) : number{ + return 5; + } } }); From fed186e128af1b3eda45154f0556bb94f7611b4a Mon Sep 17 00:00:00 2001 From: cem Date: Thu, 14 Jul 2016 16:47:52 -0400 Subject: [PATCH 18/49] minor fixes --- client/imports/lab/methods.ts | 6 +++--- server/main.js | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/imports/lab/methods.ts b/client/imports/lab/methods.ts index 01e8b62f..a738d916 100644 --- a/client/imports/lab/methods.ts +++ b/client/imports/lab/methods.ts @@ -2,8 +2,8 @@ Meteor.methods({ 'prepareLab': function(courseId : String ,labId : Number){ return "here"; }, - 'tyLab': function() : number{ - return 3; - } + 'startLab': function(callback : any){}, + 'nextTask': function(callback : any){}, + 'endLab': function(callback : any){} }); diff --git a/server/main.js b/server/main.js index fc2e97a4..da5faa03 100644 --- a/server/main.js +++ b/server/main.js @@ -43,4 +43,3 @@ var NodeCache = require('node-cache'); //import Meteor Methods import "./imports/lab/methods.ts" -import "./imports/lab/methods2.ts" From 39e8e38677702099f80882adf4adad0f5134f913 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 15 Jul 2016 10:24:50 -0400 Subject: [PATCH 19/49] A --- client/imports/course/methods.ts | 5 + client/imports/lab/methods.ts | 6 +- .../imports/ui/components/explore/explore.ts | 2 +- .../imports/ui/components/explore/search.ts | 2 +- .../ui/components/gradelist/gradelist.ts | 2 +- .../imports/ui/components/lablist/lablist.ts | 2 +- .../ui/components/markdown/markdown.html | 4 +- .../ui/components/markdown/markdown.ts | 18 +- .../ui/components/mdeditor/mdeditor.ts | 3 +- .../ui/components/userlist/userlist.html | 7 + .../ui/components/userlist/userlist.ts | 53 ++++++ client/imports/ui/pages/course/course.ts | 11 +- client/imports/ui/pages/course/gradelist.ts | 8 +- client/imports/ui/pages/course/lablist.ts | 8 +- client/imports/ui/pages/explore/explore.html | 2 +- client/imports/ui/pages/explore/explore.ts | 34 ++-- .../imports/ui/pages/instructor/instructor.ts | 4 +- client/imports/ui/pages/lab/taskview.ts | 13 +- client/style/base/_toolbar.scss | 35 +++- client/style/course/_courseview.scss | 3 + client/style/lab/_labview.scss | 155 +++++++++--------- client/tuxlab.html | 14 +- client/tuxlab.ts | 17 +- server/imports/course/methods.ts | 46 ++++++ server/main.js | 2 +- 25 files changed, 302 insertions(+), 154 deletions(-) create mode 100644 client/imports/course/methods.ts create mode 100644 client/imports/ui/components/userlist/userlist.html create mode 100644 client/imports/ui/components/userlist/userlist.ts create mode 100644 server/imports/course/methods.ts diff --git a/client/imports/course/methods.ts b/client/imports/course/methods.ts new file mode 100644 index 00000000..9a6fb20e --- /dev/null +++ b/client/imports/course/methods.ts @@ -0,0 +1,5 @@ +Meteor.methods({ + 'search_courses': function(text : String){ + console.log("searching courses"); + } +}); diff --git a/client/imports/lab/methods.ts b/client/imports/lab/methods.ts index 01e8b62f..a738d916 100644 --- a/client/imports/lab/methods.ts +++ b/client/imports/lab/methods.ts @@ -2,8 +2,8 @@ Meteor.methods({ 'prepareLab': function(courseId : String ,labId : Number){ return "here"; }, - 'tyLab': function() : number{ - return 3; - } + 'startLab': function(callback : any){}, + 'nextTask': function(callback : any){}, + 'endLab': function(callback : any){} }); diff --git a/client/imports/ui/components/explore/explore.ts b/client/imports/ui/components/explore/explore.ts index 2a2eab76..2c7e16ed 100644 --- a/client/imports/ui/components/explore/explore.ts +++ b/client/imports/ui/components/explore/explore.ts @@ -50,7 +50,7 @@ export class ExploreView extends MeteorComponent { mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); mdIconRegistry.setDefaultFontSetClass('tuxicon'); - this.subscribe('all-courses', () => { + this.subscribe('explore-courses', () => { this.courses = courses.find().fetch(); }, true); } diff --git a/client/imports/ui/components/explore/search.ts b/client/imports/ui/components/explore/search.ts index 53a70f2c..11105c12 100644 --- a/client/imports/ui/components/explore/search.ts +++ b/client/imports/ui/components/explore/search.ts @@ -22,7 +22,7 @@ import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; // Courses Database Imports - import { courses } from '../../../../../collections/courses'; + import { courses } from '../../../../../collections/courses.ts'; // Define SearchView Component @Component({ diff --git a/client/imports/ui/components/gradelist/gradelist.ts b/client/imports/ui/components/gradelist/gradelist.ts index 01ca0665..b39304d2 100644 --- a/client/imports/ui/components/gradelist/gradelist.ts +++ b/client/imports/ui/components/gradelist/gradelist.ts @@ -19,7 +19,7 @@ import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; // Course Records Import - import { course_records } from '../../../../../collections/course_records'; + import { course_records } from '../../../../../collections/course_records.ts'; @InjectUser("user") diff --git a/client/imports/ui/components/lablist/lablist.ts b/client/imports/ui/components/lablist/lablist.ts index bba026d7..3f6b38c4 100644 --- a/client/imports/ui/components/lablist/lablist.ts +++ b/client/imports/ui/components/lablist/lablist.ts @@ -20,7 +20,7 @@ import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; // course_record database imports - import { course_records } from '../../../../../collections/course_records'; + import { course_records } from '../../../../../collections/course_records.ts'; @InjectUser("user") diff --git a/client/imports/ui/components/markdown/markdown.html b/client/imports/ui/components/markdown/markdown.html index 5a47ae65..24772322 100644 --- a/client/imports/ui/components/markdown/markdown.html +++ b/client/imports/ui/components/markdown/markdown.html @@ -9,9 +9,9 @@ -

Task Name Here

+

{{ labName }}

-

3/10

+

{{ labProgress }}

diff --git a/client/imports/ui/components/markdown/markdown.ts b/client/imports/ui/components/markdown/markdown.ts index d3d62526..38c9bb69 100644 --- a/client/imports/ui/components/markdown/markdown.ts +++ b/client/imports/ui/components/markdown/markdown.ts @@ -21,7 +21,8 @@ // Icon import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; - + + import { LabData } from '../../pages/lab/taskview.ts'; // Markdown Imports /// import * as marked from 'marked'; @@ -44,18 +45,21 @@ // Export MarkdownView Class export class MarkdownView { - //TODO: Replace with markdown from the database - data = "# Markdown\n This is a short **markdown** string, and this is *italic* text. Here is some ***bold and italic*** text. \n ## Subtitle here"; - convertedData = this.data; + data = (new LabData).labMarkdown; + convertedData: String; + labName = "Lab Name Here"; + labProgress = "3/10"; constructor(mdIconRegistry: MdIconRegistry) { // Create Icon Font mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); mdIconRegistry.setDefaultFontSetClass('tuxicon'); - + // Parse markdown string let md = marked.setOptions({}); - this.convertedData = md.parse(this.data); + if(typeof this.data !== "undefined") { + this.convertedData = md.parse(this.data); + } } -} +} \ No newline at end of file diff --git a/client/imports/ui/components/mdeditor/mdeditor.ts b/client/imports/ui/components/mdeditor/mdeditor.ts index ff7e98a7..3fd1573e 100644 --- a/client/imports/ui/components/mdeditor/mdeditor.ts +++ b/client/imports/ui/components/mdeditor/mdeditor.ts @@ -17,8 +17,7 @@ import { OVERLAY_PROVIDERS } from '@angular2-material/core/overlay/overlay'; // Toolbar - import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; - import "../../../../../node_modules/@angular2-material/toolbar/toolbar.css"; + import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; // Icon import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; diff --git a/client/imports/ui/components/userlist/userlist.html b/client/imports/ui/components/userlist/userlist.html new file mode 100644 index 00000000..0fb1f492 --- /dev/null +++ b/client/imports/ui/components/userlist/userlist.html @@ -0,0 +1,7 @@ +
+ + +

Course Number User List

+
+
+
\ No newline at end of file diff --git a/client/imports/ui/components/userlist/userlist.ts b/client/imports/ui/components/userlist/userlist.ts new file mode 100644 index 00000000..4ef7a3d2 --- /dev/null +++ b/client/imports/ui/components/userlist/userlist.ts @@ -0,0 +1,53 @@ +// Meteor Imports + import { Meteor } from 'meteor/meteor'; + import { Mongo } from 'meteor/mongo'; + import 'reflect-metadata'; + import 'zone.js/dist/zone'; + +// Angular Imports + import { Component, ViewEncapsulation, provide } from '@angular/core'; + import { bootstrap } from 'angular2-meteor-auto-bootstrap'; + import { APP_BASE_HREF } from '@angular/common'; + import { HTTP_PROVIDERS } from '@angular/http'; + import { InjectUser } from 'angular2-meteor-accounts-ui'; + +// Angular Material Imports + import { MATERIAL_PROVIDERS, MATERIAL_DIRECTIVES } from 'ng2-material'; + import { MeteorComponent } from 'angular2-meteor'; + +// Icon + import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; + +// Course Records Import + import { course_records } from '../../../../../collections/course_records.ts'; + +// Define UserList Component + @Component({ + selector: 'tuxlab-userlist', + templateUrl: '/client/imports/ui/components/userlist/userlist.html', + directives: [ + MATERIAL_DIRECTIVES, + MD_ICON_DIRECTIVES], + viewProviders: [ MdIconRegistry ], + encapsulation: ViewEncapsulation.None + }) + +// Export UserList Class + export class UserList extends MeteorComponent { + user: Meteor.User; + courseId: String; + userIds: Array; + constructor(mdIconRegistry: MdIconRegistry) { + super(); + // Create Icon Font + mdIconRegistry.registerFontClassAlias('tux', 'tuxicon'); + mdIconRegistry.setDefaultFontSetClass('tuxicon'); + + this.subscribe('course-records', this.courseId, () => { + let courseRecords = course_records.find({ course_id: this.courseId }); + this.userIds = courseRecords.map(function(record) { + return (record).user_id; + }); + }, true); + } + } diff --git a/client/imports/ui/pages/course/course.ts b/client/imports/ui/pages/course/course.ts index c36c6587..5c89bf51 100644 --- a/client/imports/ui/pages/course/course.ts +++ b/client/imports/ui/pages/course/course.ts @@ -20,12 +20,12 @@ import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; // LabList and Grades import - import { LabList } from "../../components/lablist/lablist"; - import { GradeList } from "../../components/gradelist/gradelist"; + import { LabList } from "../../components/lablist/lablist.ts"; + import { GradeList } from "../../components/gradelist/gradelist.ts"; // Courses and Course Record Imports - import { courses } from "../../../../../collections/courses"; - import { course_records } from "../../../../../collections/course_records"; + import { courses } from "../../../../../collections/courses.ts"; + import { course_records } from "../../../../../collections/course_records.ts"; // Define CourseView Component @Component({ @@ -56,8 +56,7 @@ mdIconRegistry.setDefaultFontSetClass('tuxicon'); // Display Course Toolbar - document.getElementById('course-toolbar').style.display = "block"; - + document.getElementById('course-toolbar').className += " block"; // Activate toolbar button document.getElementById('toolbar-course').className += " active-button"; diff --git a/client/imports/ui/pages/course/gradelist.ts b/client/imports/ui/pages/course/gradelist.ts index 4dc5a82a..4cde7b61 100644 --- a/client/imports/ui/pages/course/gradelist.ts +++ b/client/imports/ui/pages/course/gradelist.ts @@ -19,7 +19,7 @@ import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; // Grades import - import { GradeList } from "../../components/gradelist/gradelist"; + import { GradeList } from "../../components/gradelist/gradelist.ts"; // Define GradeView Component @Component({ @@ -41,11 +41,9 @@ mdIconRegistry.setDefaultFontSetClass('tuxicon'); // Display Course Toolbar - document.getElementById('course-toolbar').style.display = "block"; - + document.getElementById('course-toolbar').className += "block"; + // Activate toolbar button document.getElementById('toolbar-grades').className += "active-button"; - - document.getElementById('tux-content').style.marginTop = "20px"; } } diff --git a/client/imports/ui/pages/course/lablist.ts b/client/imports/ui/pages/course/lablist.ts index 81d9cf5c..d4337f4b 100644 --- a/client/imports/ui/pages/course/lablist.ts +++ b/client/imports/ui/pages/course/lablist.ts @@ -19,7 +19,7 @@ import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon'; // LabList import - import { LabList } from "../../components/lablist/lablist"; + import { LabList } from "../../components/lablist/lablist.ts"; // Define LabsView Component @Component({ @@ -41,11 +41,9 @@ mdIconRegistry.setDefaultFontSetClass('tuxicon'); // Display Course Toolbar - document.getElementById('course-toolbar').style.display = "block"; - + document.getElementById('course-toolbar').className += "block"; + // Activate toolbar button document.getElementById('toolbar-labs').className += "active-button"; - - document.getElementById('tux-content').style.marginTop = "20px"; } } diff --git a/client/imports/ui/pages/explore/explore.html b/client/imports/ui/pages/explore/explore.html index b11c5d5d..7cfefa97 100644 --- a/client/imports/ui/pages/explore/explore.html +++ b/client/imports/ui/pages/explore/explore.html @@ -8,7 +8,7 @@ @@ -88,7 +87,7 @@

{{ user.profile.school }}

- +
@@ -98,6 +97,15 @@

{{ user.profile.school }}

+ +
+ Home + Labs + Grades + More + More +
+
diff --git a/client/tuxlab.ts b/client/tuxlab.ts index bbedf0fb..fd4a625c 100644 --- a/client/tuxlab.ts +++ b/client/tuxlab.ts @@ -12,14 +12,15 @@ import { APP_BASE_HREF, CORE_DIRECTIVES } from '@angular/common'; import { HTTP_PROVIDERS } from '@angular/http'; - + import { disableDeprecatedForms, provideForms } from '@angular/forms'; import { InjectUser } from 'angular2-meteor-accounts-ui'; - + // Angular Material Imports import { MATERIAL_PROVIDERS, MATERIAL_DIRECTIVES } from 'ng2-material'; import { MD_ICON_DIRECTIVES, MdIconRegistry } from '@angular2-material/icon' import { MD_SIDENAV_DIRECTIVES } from '@angular2-material/sidenav'; import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; + import { ResponsiveState, RESPONSIVE_DIRECTIVES } from 'responsive-directives-angular2'; import { MeteorComponent } from 'angular2-meteor'; @@ -61,10 +62,12 @@ class TuxLab extends MeteorComponent { bootstrap(TuxLab, [ ResponsiveState, - MATERIAL_PROVIDERS, - HTTP_PROVIDERS, - MdIconRegistry, - ROUTE_PROVIDERS, - provide(APP_BASE_HREF, { useValue: '/' }), + disableDeprecatedForms(), + provideForms(), + MATERIAL_PROVIDERS, + HTTP_PROVIDERS, + MdIconRegistry, + ROUTE_PROVIDERS, + provide(APP_BASE_HREF, { useValue: '/' }), provide(PLATFORM_DIRECTIVES, { useValue: [RESPONSIVE_DIRECTIVES], multi: true }) ]); diff --git a/server/imports/course/methods.ts b/server/imports/course/methods.ts new file mode 100644 index 00000000..769dee1c --- /dev/null +++ b/server/imports/course/methods.ts @@ -0,0 +1,46 @@ +var async = require ('async'); +var future = require('fibers/future'); + +Meteor.methods({ + 'search_courses': function(text : String, results_per_page : Number, page_no : Number) { + + var courses = Collections.courses; + + var search_pattern = new RegExp(text,"i"); + if (results_per_page <= 0 || results_per_page > 200) results_per_page = 200; + + var search_object = + {$and : [ + {"hidden" : false}, + {$or : [ + {"course_number" : search_pattern}, + {$where: "this.course_number.replace(/[ .-]/g,'') == '"+text+"'"}, + {"course_name" : search_pattern} + ]} + ]}; + + var search_options = + {limit : results_per_page, + skip : results_per_page * page_no, + fields : { + "course_number" : 1, + "course_name" : 1, + "instructor_ids" : 1, + "course_description" : 1} + }; + + var result = new future(); + + async.parallel( + { + "course_count" : function(callback) {callback(null, courses.find(search_object).count());}, + "course_results" : function(callback) {callback(null, courses.find(search_object, search_options).fetch());} + }, + function(err, results) { + if(err) result.throw(error); + result.return(results); + }); + + return result.wait(); + } +}); diff --git a/server/main.js b/server/main.js index fc2e97a4..7ad9ff1b 100644 --- a/server/main.js +++ b/server/main.js @@ -43,4 +43,4 @@ var NodeCache = require('node-cache'); //import Meteor Methods import "./imports/lab/methods.ts" -import "./imports/lab/methods2.ts" +import "./imports/course/methods.ts" From ddf5730c0e5da770bcc17273932f4d5a5782c169 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 15 Jul 2016 11:04:09 -0400 Subject: [PATCH 20/49] api changes --- server/imports/api/lab.env.js | 2 +- .../{lab.session.d.t.s => lab.session.d.ts} | 0 server/imports/api/lab.session.js | 4 ++-- server/imports/lab/methods.ts | 18 +++++++++++++++++- 4 files changed, 20 insertions(+), 4 deletions(-) rename server/imports/api/{lab.session.d.t.s => lab.session.d.ts} (100%) diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index d67d5504..db49ef91 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -376,7 +376,7 @@ env.prototype.shell = function(vmName,command,opts) { */ env.prototype.getPass = function(vmName,callback){ this.shell1(vmName, "cat /pass") - .then(function(sOut){ callback(sOut); }, function(s1,s2,s3){callback(s1,s2,s3);}); + .then(function(sOut){ callback(null,null,sOut); }, function(s1,s2,s3){callback(s1,s2,s3);}); } env.prototype.getNetwork = function() {} //Don't know what this does env.prototype.getVolume = function() {} //Don't know what this does diff --git a/server/imports/api/lab.session.d.t.s b/server/imports/api/lab.session.d.ts similarity index 100% rename from server/imports/api/lab.session.d.t.s rename to server/imports/api/lab.session.d.ts diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index 33001bae..97f593a8 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -15,8 +15,8 @@ session.prototype.init = function(user,labId,callback){ this.env.setUser(user); // Get Metadata from Database - var lab = Collections.labs.findOne({_id: lab_id}, {fields: {'file' : 0}}).fetch(); - if(lab.length < 0){ + var lab = Collections.labs.findOne({_id: labId}, {fields: {'file' : 0}}); + if(!lab || lab.length < 0){ callback(new Error("Lab Not Found.", null)); } else{ diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 4795f6fa..5248b01a 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -5,8 +5,24 @@ Meteor.methods({ * callback: (err,parseTasks,labExec) */ 'prepareLab': function(labId : number,callback : any){ - var lab = require('../api/lab.session.js'); + var session = require('../api/lab.session.js'); var uId = Meteor.userId(); + session.init(uId,labId,function(err,res){ + session.env.getPass(function(err1,err2,pass){ + if(err1){ + TuxLog.log("debug","error getting pass from labVm container: "+err1); + callback("Internal Service Error",null); + } + else if(err2){ + TuxLog.log("debug","error getting pass from labVm container: "+err2); + callback("Internal Service Error",null); + } + else{ + var resolve = {'pass': pass} + callback(null,resolve); + } + }); + }); return uId; /**lab.init(userId,labId,cb) * cb(err,parsedTasks) cache session in cb, get rid of parsedTasks if unnecessary From 7fd5d14be05c18d1711852ebd72cf6579e930d4c Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 15 Jul 2016 11:30:42 -0400 Subject: [PATCH 21/49] fixed api --- server/imports/api/lab.env.js | 5 ++++- server/imports/api/lab.session.js | 6 +++--- server/imports/lab/methods.ts | 23 +++++------------------ 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index 8a4bc550..3e7dac71 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -370,7 +370,10 @@ env.prototype.shell = function(vmName,command,opts) { */ env.prototype.getPass = function(vmName,callback){ this.shell1(vmName, "cat /pass") - .then(function(sOut){ callback(null,null,sOut); }, function(s1,s2,s3){callback(s1,s2,s3);}); + .then(function(sOut){ callback(null,sOut); }, function(s1,s2,s3){ + if(s1){ callback(s1,s3) } + else{ callback(s2,s3) } + }); } env.prototype.getNetwork = function() {} //Don't know what this does env.prototype.getVolume = function() {} //Don't know what this does diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index 97f593a8..b4b113b6 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -45,13 +45,13 @@ session.prototype.init = function(user,labId,callback){ }); slf.lab.taskNo = 0; - callback(null, lab.tasks); + slf.env.getPass(callback); } else{ // Get LabFile from Cache slf.lab.taskNo = 0; slf.lab = value; - callback(null, lab.tasks); + slf.env.getPass(callback); } }); } @@ -125,4 +125,4 @@ session.prototype.end = function(callback){ }); } -module.exports = new session(); +module.exports = session; diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 5248b01a..8bf46852 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,28 +1,15 @@ declare var Collections : any; +var Session = require('../api/lab.session.js'); Meteor.methods({ /**prepareLab: prepares a labExec object for the current user * takes the id of the lab and a callback as parameter - * callback: (err,parseTasks,labExec) + * callback: (err,pass) */ 'prepareLab': function(labId : number,callback : any){ - var session = require('../api/lab.session.js'); + var session = Session(); var uId = Meteor.userId(); - session.init(uId,labId,function(err,res){ - session.env.getPass(function(err1,err2,pass){ - if(err1){ - TuxLog.log("debug","error getting pass from labVm container: "+err1); - callback("Internal Service Error",null); - } - else if(err2){ - TuxLog.log("debug","error getting pass from labVm container: "+err2); - callback("Internal Service Error",null); - } - else{ - var resolve = {'pass': pass} - callback(null,resolve); - } - }); - }); + session.init(uId,labId,callback); + return uId; /**lab.init(userId,labId,cb) * cb(err,parsedTasks) cache session in cb, get rid of parsedTasks if unnecessary From 0b5ef751cf13a4c24df21f94a09d01dddfb903fb Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 15 Jul 2016 11:36:08 -0400 Subject: [PATCH 22/49] comments --- server/imports/lab/methods.ts | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index ddde604f..a3758fee 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -5,6 +5,7 @@ Meteor.methods({ /**prepareLab: prepares a labExec object for the current user * takes the id of the lab and a callback as parameter * callback: (err,pass) + * implement loading wheel, md fetch, course record create in callback */ 'prepareLab': function(labId : number,callback : any){ var session = Session(); @@ -12,26 +13,6 @@ Meteor.methods({ session.init(uId,labId,callback); return uId; - /**lab.init(userId,labId,cb) - * cb(err,parsedTasks) cache session in cb, get rid of parsedTasks if unnecessary - * implement loading wheel here -in callback - * session.env.getPass(cb) callback(pass) is called, call this here and then call the prepareLab callback - * what to put in res of callback(err,res)? session obj? true/false? session id?... - * get task md -frontend - * create course record - */ - session.init(userid,labId,function(err,res){ - session.env.getPass(function(err,pass){ - if(err){ - TuxLog.log("debug","error getting pass from labVm container: "+err); - callback("Internal Service Error",null); - } - else{ - var resp = {'pass': pass} - callback(null, resp); - } - }); - }); }, 'startLab': function(callback : any){ /** somehow get session, From f0cf5299dddd113e262c9413cfebd6b6a21b29da Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 15 Jul 2016 14:14:58 -0400 Subject: [PATCH 23/49] minor changes --- collections/labs.ts | 11 ++++++-- server/imports/api/lab.js | 3 +- server/imports/api/lab.session.d.ts | 2 +- server/imports/api/lab.session.js | 43 ++++++++++++++++++----------- server/imports/lab/cache.js | 4 +-- server/imports/lab/checkLab.js | 17 ++++++++---- server/imports/lab/methods.ts | 28 +++++++++---------- 7 files changed, 66 insertions(+), 42 deletions(-) diff --git a/collections/labs.ts b/collections/labs.ts index 25dea57d..bbf06216 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -106,10 +106,17 @@ labs.allow({ if (typeof fieldNames === "undefined"){ console.log("inserting"); if(!(doc.course_id && doc.file && //check for lab fields - (Meteor.isServer || Roles.isInstructorFor(doc.course_id,userid))&& //check for instructor authorization - validateLab(doc.file))){ //check for labfile errors + (Meteor.isServer || Roles.isInstructorFor(doc.course_id,userid)))){//check for instructor authorization return false; } + else{ + var lastTask = validateLab(doc.file); + if(!lastTask){ + return false; } + else{ + return lastTask.prnt.titleList; + } + } //TODO @CEM: Validate Lab //TODO @CEM: Generate tasks array diff --git a/server/imports/api/lab.js b/server/imports/api/lab.js index 1b55d631..6e2795aa 100644 --- a/server/imports/api/lab.js +++ b/server/imports/api/lab.js @@ -17,6 +17,7 @@ lab.prototype.init = function(){ lab.prototype.currentTask = null; lab.prototype.taskList = []; +lab.prototype.titleList = []; lab.prototype.setup; lab.prototype.tasks; lab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ @@ -25,13 +26,13 @@ lab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ setupFn: sFn, verifyFn: vFn, opts: opt, - markdown: mdown, title: ttl, next: null, completed: false, nextTask: function(tsk){ this.next = tsk; this.prnt.taskList.push(tsk); + this.prnt.titleList.push(tsk.title); return tsk; }, isLast: function(){ return this.next === null; } diff --git a/server/imports/api/lab.session.d.ts b/server/imports/api/lab.session.d.ts index 5fbac7a5..b9fdc908 100644 --- a/server/imports/api/lab.session.d.ts +++ b/server/imports/api/lab.session.d.ts @@ -2,7 +2,7 @@ namespace lab_exec { interface labExec{ var env : any; var tuxlab : any; - function init(user : string, labId : number, callback : any) + function init(user : string, labId : string, callback : any) function parseTasks() : any function start(callback : any) : any function next(callback : any) : any diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index b4b113b6..ae1d5056 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -45,31 +45,42 @@ session.prototype.init = function(user,labId,callback){ }); slf.lab.taskNo = 0; - slf.env.getPass(callback); + SessionCache.add(userid,labid,slf,function(err){ + if(err){ + callback(err,null); + } + else{ + slf.start(function(error){ + if(err){ + callback(err,null); + } + else{ + slf.env.getPass(callback); + } + }); + } + }); } else{ // Get LabFile from Cache slf.lab.taskNo = 0; slf.lab = value; - slf.env.getPass(callback); + SessionCache.add(userid,labid,slf,function(err){ + if(err){ + callback(err,null); + } + else{ + slf.env.getPass(callback); + } + }); } }); } } -session.prototype.parseTasks = function(){ - var slf = this; - return this.lab.taskList.map(function(task,i){ - if(i <= slf.lab.taskNo){ - return {title: task.title, markdown: task.markdown}; - } - return {title: task.title, markdown: null}; - }); -} - /* start: runs setup and moves task header to first task - * runs callback(err,res) on err if there is an error, - * (null,parseTasks) no error + * runs callback(err) on err if there is an error, + * (null) no error */ session.prototype.start = function(callback){ var slf = this; @@ -79,10 +90,10 @@ session.prototype.start = function(callback){ var tasks = this.lab.tasks(this.env); if(!this.lab.currentTask.next){ TuxLog.log('labfile_error','labfile tasks not properly chained at start'); - callback("Internal error",null); + callback("Internal error"); } this.lab.currentTask = this.lab.currentTask.next; - this.currentTask.sFn().then(function(){ callback(null,slf.parseTasks(0)); }); + this.currentTask.sFn().then(function(){ callback(null); }); } /* next: verifies that task is completed diff --git a/server/imports/lab/cache.js b/server/imports/lab/cache.js index 8f8f741b..5817a1b9 100644 --- a/server/imports/lab/cache.js +++ b/server/imports/lab/cache.js @@ -36,10 +36,10 @@ var NodeCache = require('node-cache'); SessionCache._NodeCache.get(userid+'#'+labid, function(err, value){ if(err){ TuxLog.log('warn', "SessionCache NodeCache Error."); - callback(null); + callback(err,null); } else if(value !== undefined){ - callback(value); + callback(null,value); } else{ var data = etcd.get('/tuxlab/sessions/'+userid+'/'+labid, function(err, value){ diff --git a/server/imports/lab/checkLab.js b/server/imports/lab/checkLab.js index 3b638493..051ab932 100644 --- a/server/imports/lab/checkLab.js +++ b/server/imports/lab/checkLab.js @@ -3,11 +3,16 @@ module.exports = function(str){ if(!str) { return false; } //check for file import var tux = eval(str); - //var s = tuxlab; var tuxOrig = require('./tuxlab.js'); - return ((typeof tux != "undefined") && - (typeof tux.setup === 'function') && //check for instructor field types - (typeof tux.tasks === 'function') && - (tux.init.toString() === tuxOrig.init.toString()) && //check for unchanged - (tux.newTask.toString() === tuxOrig.newTask.toString())); + if(((typeof tux != "undefined") && + (typeof tux.setup === 'function') && //check for instructor field types + (typeof tux.tasks === 'function') && + (typeof tux.tasks() != 'undefined') && + (tux.init.toString() === tuxOrig.init.toString()) && //check for unchanged + (tux.newTask.toString() === tuxOrig.newTask.toString()))){ + return null; + } + else{ + return tux.titleList; + } } diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index a3758fee..fb6bfa09 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,5 +1,5 @@ declare var Collections : any; -var Session = require('../api/lab.session.js'); +var LabSession = require('../api/lab.session.js'); Meteor.methods({ /**prepareLab: prepares a labExec object for the current user @@ -7,27 +7,27 @@ Meteor.methods({ * callback: (err,pass) * implement loading wheel, md fetch, course record create in callback */ - 'prepareLab': function(labId : number,callback : any){ - var session = Session(); + 'prepareLab': function(user : string, labId : string,callback : any){ + var session = LabSession(); var uId = Meteor.userId(); session.init(uId,labId,callback); - - return uId; }, - 'startLab': function(callback : any){ - /** somehow get session, - * cache/ram/db/parameter - * session.start(cb) - * call startLab callback(err,res) in session.start cb - */ - }, - 'nextTask': function(callback : any){ + 'nextTask': function(labId : string, callback : any){ /**session.next(cb) * cb(err,res) implement loading wheel here * call nextTask callback(err,res) in cb * change task markdown -frontend * change course records if passed */ + var uId = Meteor.userId(); + SessionCache.get(uId,labId,function(err,res){ + if(err || !res){ + console.log("Internal Service Error"); + } + else{ + + } + }); }, 'endLab': function(callback : any){ /**session.end(cb) @@ -39,4 +39,4 @@ Meteor.methods({ * remove all vms and deleterecords after lab is completed for good. -highly optional */ } -]); +}); From dcf231785ba24c9512dd4164f532c1163650bf88 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 15 Jul 2016 14:24:43 -0400 Subject: [PATCH 24/49] minor fixes --- collections/labs.ts | 4 +--- server/imports/lab/checkLab.js | 1 - server/imports/lab/methods.ts | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/collections/labs.ts b/collections/labs.ts index e63ad65e..1ec91337 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -103,7 +103,7 @@ labs.allow({ var LabValidator = function(userid, doc, fieldNames?, modifier?, options?){ if (typeof fieldNames === "undefined"){ if(!(doc.course_id && doc.file && //check for lab fields - (Meteor.isServer || Roles.isInstructorFor(doc.course_id,userid)))){//check for instructor authorization + Roles.isInstructorFor(doc.course_id,userid))){//check for instructor authorization return false; } else{ @@ -115,8 +115,6 @@ labs.allow({ } } - //TODO @CEM: Validate Lab - //TODO @CEM: Generate tasks array } else if(fieldNames.includes('tasks') && !fieldNames.includes('file')){ return false; diff --git a/server/imports/lab/checkLab.js b/server/imports/lab/checkLab.js index 6e7601f0..f87c9c81 100644 --- a/server/imports/lab/checkLab.js +++ b/server/imports/lab/checkLab.js @@ -6,7 +6,6 @@ var tuxOrig = require('./lab.js'); module.exports = function(str){ if(!str) { return false; } //check for file import var tux = eval(str); - var tuxOrig = require('./tuxlab.js'); if(((typeof tux != "undefined") && (typeof tux.setup === 'function') && //check for instructor field types (typeof tux.tasks === 'function') && diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 0e777413..c003f4e0 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,7 +1,7 @@ declare var Collections : any; var LabSession = require('../api/lab.session.js'); declare var TuxLog : any; - +declare var SessionCache : any; Meteor.methods({ /**prepareLab: prepares a labExec object for the current user From 574d27352490566d94833c94c33f4277731461a5 Mon Sep 17 00:00:00 2001 From: Cem Ersoz Date: Fri, 15 Jul 2016 14:28:31 -0400 Subject: [PATCH 25/49] api changes (#126) * issue 32 fixed * removed swp * fixed nconf issues * issue 82, 84 fixes * fixed #82 * isse #77 * fixed tests * fixed files * fixed tests master * fixed comment * moved validator * removed duplicate file * fixed tests, removed duplicate underscore, publish * changes * fixed methods.ts import * fixed issues w methods * fixes * minor fixes * A * api changes * fixed api * comments * minor changes * minor fixes --- collections/labs.ts | 17 ++++++++---- server/imports/api/lab.js | 3 +- server/imports/api/lab.session.d.ts | 2 +- server/imports/api/lab.session.js | 43 ++++++++++++++++++----------- server/imports/lab/cache.js | 4 +-- server/imports/lab/checkLab.js | 17 ++++++++---- server/imports/lab/methods.ts | 26 +++++++++-------- 7 files changed, 69 insertions(+), 43 deletions(-) diff --git a/collections/labs.ts b/collections/labs.ts index bccba184..1ec91337 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -103,11 +103,18 @@ labs.allow({ var LabValidator = function(userid, doc, fieldNames?, modifier?, options?){ if (typeof fieldNames === "undefined"){ if(!(doc.course_id && doc.file && //check for lab fields - (Roles.isInstructorFor(doc.course_id,userid)) && //check for instructor authorization - validateLab(doc.file)) - ){ //check for labfile errors - return false; - } + Roles.isInstructorFor(doc.course_id,userid))){//check for instructor authorization + return false; + } + else{ + var titleList = validateLab(doc.file); + if(!titleList){ + return false; } + else{ + return titleList; + } + } + } else if(fieldNames.includes('tasks') && !fieldNames.includes('file')){ return false; diff --git a/server/imports/api/lab.js b/server/imports/api/lab.js index 64decd4c..a33bf79b 100644 --- a/server/imports/api/lab.js +++ b/server/imports/api/lab.js @@ -17,6 +17,7 @@ lab.prototype.init = function(){ lab.prototype.currentTask = null; lab.prototype.taskList = []; +lab.prototype.titleList = []; lab.prototype.setup; lab.prototype.tasks; lab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ @@ -25,13 +26,13 @@ lab.prototype.newTask = function(ttl, mdown,sFn, vFn, opt){ setupFn: sFn, verifyFn: vFn, opts: opt, - markdown: mdown, title: ttl, next: null, completed: false, nextTask: function(tsk){ this.next = tsk; this.prnt.taskList.push(tsk); + this.prnt.titleList.push(tsk.title); return tsk; }, isLast: function(){ return this.next === null; } diff --git a/server/imports/api/lab.session.d.ts b/server/imports/api/lab.session.d.ts index 5fbac7a5..b9fdc908 100644 --- a/server/imports/api/lab.session.d.ts +++ b/server/imports/api/lab.session.d.ts @@ -2,7 +2,7 @@ namespace lab_exec { interface labExec{ var env : any; var tuxlab : any; - function init(user : string, labId : number, callback : any) + function init(user : string, labId : string, callback : any) function parseTasks() : any function start(callback : any) : any function next(callback : any) : any diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index b4b113b6..ae1d5056 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -45,31 +45,42 @@ session.prototype.init = function(user,labId,callback){ }); slf.lab.taskNo = 0; - slf.env.getPass(callback); + SessionCache.add(userid,labid,slf,function(err){ + if(err){ + callback(err,null); + } + else{ + slf.start(function(error){ + if(err){ + callback(err,null); + } + else{ + slf.env.getPass(callback); + } + }); + } + }); } else{ // Get LabFile from Cache slf.lab.taskNo = 0; slf.lab = value; - slf.env.getPass(callback); + SessionCache.add(userid,labid,slf,function(err){ + if(err){ + callback(err,null); + } + else{ + slf.env.getPass(callback); + } + }); } }); } } -session.prototype.parseTasks = function(){ - var slf = this; - return this.lab.taskList.map(function(task,i){ - if(i <= slf.lab.taskNo){ - return {title: task.title, markdown: task.markdown}; - } - return {title: task.title, markdown: null}; - }); -} - /* start: runs setup and moves task header to first task - * runs callback(err,res) on err if there is an error, - * (null,parseTasks) no error + * runs callback(err) on err if there is an error, + * (null) no error */ session.prototype.start = function(callback){ var slf = this; @@ -79,10 +90,10 @@ session.prototype.start = function(callback){ var tasks = this.lab.tasks(this.env); if(!this.lab.currentTask.next){ TuxLog.log('labfile_error','labfile tasks not properly chained at start'); - callback("Internal error",null); + callback("Internal error"); } this.lab.currentTask = this.lab.currentTask.next; - this.currentTask.sFn().then(function(){ callback(null,slf.parseTasks(0)); }); + this.currentTask.sFn().then(function(){ callback(null); }); } /* next: verifies that task is completed diff --git a/server/imports/lab/cache.js b/server/imports/lab/cache.js index 8f8f741b..5817a1b9 100644 --- a/server/imports/lab/cache.js +++ b/server/imports/lab/cache.js @@ -36,10 +36,10 @@ var NodeCache = require('node-cache'); SessionCache._NodeCache.get(userid+'#'+labid, function(err, value){ if(err){ TuxLog.log('warn', "SessionCache NodeCache Error."); - callback(null); + callback(err,null); } else if(value !== undefined){ - callback(value); + callback(null,value); } else{ var data = etcd.get('/tuxlab/sessions/'+userid+'/'+labid, function(err, value){ diff --git a/server/imports/lab/checkLab.js b/server/imports/lab/checkLab.js index cd079f53..f87c9c81 100644 --- a/server/imports/lab/checkLab.js +++ b/server/imports/lab/checkLab.js @@ -6,10 +6,15 @@ var tuxOrig = require('./lab.js'); module.exports = function(str){ if(!str) { return false; } //check for file import var tux = eval(str); - //var s = tuxlab; - return ((typeof tux != "undefined") && - (typeof tux.setup === 'function') && //check for instructor field types - (typeof tux.tasks === 'function') && - (tux.init.toString() === tuxOrig.init.toString()) && //check for unchanged - (tux.newTask.toString() === tuxOrig.newTask.toString())); + if(((typeof tux != "undefined") && + (typeof tux.setup === 'function') && //check for instructor field types + (typeof tux.tasks === 'function') && + (typeof tux.tasks() != 'undefined') && + (tux.init.toString() === tuxOrig.init.toString()) && //check for unchanged + (tux.newTask.toString() === tuxOrig.newTask.toString()))){ + return null; + } + else{ + return tux.titleList; + } } diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index ecd0e4a3..c003f4e0 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,7 +1,7 @@ declare var Collections : any; +var LabSession = require('../api/lab.session.js'); declare var TuxLog : any; - -var Session = require('../api/lab.session.js'); +declare var SessionCache : any; Meteor.methods({ /**prepareLab: prepares a labExec object for the current user @@ -9,25 +9,27 @@ Meteor.methods({ * callback: (err,pass) * implement loading wheel, md fetch, course record create in callback */ - 'prepareLab': function(labId : number, callback : any){ - var session = Session(); + 'prepareLab': function(user : string, labId : string,callback : any){ + var session = LabSession(); var uId = Meteor.userId(); session.init(uId,labId,callback); }, - 'startLab': function(callback : any){ - /** somehow get session, - * cache/ram/db/parameter - * session.start(cb) - * call startLab callback(err,res) in session.start cb - */ - }, - 'nextTask': function(callback : any){ + 'nextTask': function(labId : string, callback : any){ /**session.next(cb) * cb(err,res) implement loading wheel here * call nextTask callback(err,res) in cb * change task markdown -frontend * change course records if passed */ + var uId = Meteor.userId(); + SessionCache.get(uId,labId,function(err,res){ + if(err || !res){ + console.log("Internal Service Error"); + } + else{ + + } + }); }, 'endLab': function(callback : any){ /**session.end(cb) From 9c7ab13e907ce02e4e9d33708bcaba3431f14c83 Mon Sep 17 00:00:00 2001 From: cem Date: Fri, 15 Jul 2016 15:10:35 -0400 Subject: [PATCH 26/49] method implementations --- collections/labs.ts | 2 +- server/imports/lab/checkLab.d.ts | 2 +- server/imports/lab/checkLab.js | 3 ++- server/imports/lab/methods.ts | 15 ++++++++++++--- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/collections/labs.ts b/collections/labs.ts index 1ec91337..608614bd 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -6,7 +6,6 @@ declare var _ : any; var _ = require('underscore'); declare var validateLab : any; -var validateLab : any = require('../server/imports/lab/checkLab'); export const labs : any = new Mongo.Collection('labs'); @@ -99,6 +98,7 @@ labs.allow({ /* LAB VALIDATOR */ if(Meteor.isServer){ + var valdateLab : any = require('../server/imports/lab/checkLab.js'); Meteor.startup(function(){ var LabValidator = function(userid, doc, fieldNames?, modifier?, options?){ if (typeof fieldNames === "undefined"){ diff --git a/server/imports/lab/checkLab.d.ts b/server/imports/lab/checkLab.d.ts index 8ac614d6..e55444e0 100644 --- a/server/imports/lab/checkLab.d.ts +++ b/server/imports/lab/checkLab.d.ts @@ -1,3 +1,3 @@ declare module "validateLab" { - export function validateLab(str: string): boolean + export function validateLab(str: string): any } diff --git a/server/imports/lab/checkLab.js b/server/imports/lab/checkLab.js index f87c9c81..f633ecb5 100644 --- a/server/imports/lab/checkLab.js +++ b/server/imports/lab/checkLab.js @@ -4,7 +4,7 @@ var tuxOrig = require('./lab.js'); /// module.exports = function(str){ - if(!str) { return false; } //check for file import + if(!str) { return null; } //check for file import var tux = eval(str); if(((typeof tux != "undefined") && (typeof tux.setup === 'function') && //check for instructor field types @@ -17,4 +17,5 @@ module.exports = function(str){ else{ return tux.titleList; } + return null; } diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index c003f4e0..69cf0248 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -24,14 +24,14 @@ Meteor.methods({ var uId = Meteor.userId(); SessionCache.get(uId,labId,function(err,res){ if(err || !res){ - console.log("Internal Service Error"); + callback("Internal Service Error",null); } else{ - + res.next(callback); } }); }, - 'endLab': function(callback : any){ + 'endLab': function(labId : string, callback : any){ /**session.end(cb) * cb(err,res) * call endLab callback(err,res) in cb @@ -40,5 +40,14 @@ Meteor.methods({ * session.env.removeVm removes virtual machines. * remove all vms and deleterecords after lab is completed for good. -highly optional */ + var uId = Meteor.userId(); + SessionCache.get(uId,labId,function(err,res){ + if(err || !res){ + callback("Internal Service Error",null); + } + else{ + res.end(callback); + } + }); } }); From 2b653aa8d9a9164785eb0170bffe89dc528addf6 Mon Sep 17 00:00:00 2001 From: cem Date: Sun, 17 Jul 2016 11:41:23 -0400 Subject: [PATCH 27/49] before merge --- private/settings.env.json | 2 +- server/imports/lab/methods.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/private/settings.env.json b/private/settings.env.json index b9b45d58..015a3e74 100644 --- a/private/settings.env.json +++ b/private/settings.env.json @@ -6,7 +6,7 @@ "mongo_log_collection": "logs", - "etcd_node_ip": "192.168.56.102", + "etcd_node_ip": "localhost", "etcd_node_port": "2379", "etcd_user": "cem", "etcd_pass": "ersoz" diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 69cf0248..c539bbd9 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -9,7 +9,7 @@ Meteor.methods({ * callback: (err,pass) * implement loading wheel, md fetch, course record create in callback */ - 'prepareLab': function(user : string, labId : string,callback : any){ + 'prepareLab': function(user : string, labId : string, callback : any){ var session = LabSession(); var uId = Meteor.userId(); session.init(uId,labId,callback); From ee6d5153e2343d87613ca6e469dfef8779e48356 Mon Sep 17 00:00:00 2001 From: cem Date: Sun, 17 Jul 2016 19:21:20 -0400 Subject: [PATCH 28/49] removed testing change --- private/settings.env.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/private/settings.env.json b/private/settings.env.json index 89a5c35b..5bf82ba8 100644 --- a/private/settings.env.json +++ b/private/settings.env.json @@ -10,7 +10,7 @@ "mongo_log_collection": "logs", - "etcd_node_ip": "localhost", + "etcd_node_ip": "192.168.56.102", "etcd_node_port": "2379", "etcd_user": "cem", "etcd_pass": "ersoz" From 97d149283ee6ff429bf5d3cc5865bc58d7b63feb Mon Sep 17 00:00:00 2001 From: cem Date: Sun, 17 Jul 2016 19:22:20 -0400 Subject: [PATCH 29/49] fixed typo --- collections/labs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collections/labs.ts b/collections/labs.ts index f759b4ff..7f69b688 100644 --- a/collections/labs.ts +++ b/collections/labs.ts @@ -98,7 +98,7 @@ labs.allow({ /* LAB VALIDATOR */ if(Meteor.isServer){ - var valdateLab : any = require('../server/imports/lab/checkLab.js'); + var validateLab : any = require('../server/imports/lab/checkLab.js'); Meteor.startup(function(){ var LabValidator = function(userid, doc, fieldNames?, modifier?, options?){ From 461c6ea8eaecc342228ea9355942b7cfeb0a5f7d Mon Sep 17 00:00:00 2001 From: vagrant Date: Mon, 18 Jul 2016 16:10:29 +0000 Subject: [PATCH 30/49] fixed prepareLab --- client/imports/lab/methods.ts | 2 +- client/imports/ui/pages/lab/taskview.ts | 6 +----- private/settings.env.json | 27 +++++++++---------------- server/imports/api/lab.session.d.ts | 5 +++-- server/imports/api/lab.session.js | 15 +++++++++----- server/imports/lab/methods.ts | 10 ++++----- 6 files changed, 30 insertions(+), 35 deletions(-) diff --git a/client/imports/lab/methods.ts b/client/imports/lab/methods.ts index a738d916..7a7c0fc5 100644 --- a/client/imports/lab/methods.ts +++ b/client/imports/lab/methods.ts @@ -1,5 +1,5 @@ Meteor.methods({ - 'prepareLab': function(courseId : String ,labId : Number){ + 'prepareLab': function(courseId : string ,labId : string){ return "here"; }, 'startLab': function(callback : any){}, diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index 005f16b5..9ddea428 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -30,11 +30,7 @@ export default class TaskView extends MeteorComponent { constructor() { super(); - var response = function(err, res){ - console.log("Finished!", err, res); - } - - Meteor.call('prepareLab',{courseId: "1", labId: 1, callback: response}, function(err,res){ + Meteor.call('prepareLab',{courseId: "1", labId: "1"}, function(err,res){ console.log("fired",err,res); }); } diff --git a/private/settings.env.json b/private/settings.env.json index 5bf82ba8..fae9536b 100644 --- a/private/settings.env.json +++ b/private/settings.env.json @@ -1,18 +1,11 @@ -{ - "key_private" : "/etc/ssl/local/host.key", - "key_public" : "/etc/ssl/local/host.key.pub", - "key_ca" : "/etc/ssl/local/host.key.ca", - - "swarm_node_ip": "10.100.1.10", - "swarm_node_port": "4000", - - "default_image": "alpine", - - "mongo_log_collection": "logs", - - "etcd_node_ip": "192.168.56.102", - "etcd_node_port": "2379", - "etcd_user": "cem", - "etcd_pass": "ersoz" - +{ + "swarm_node_ip" : "10.100.1.10", + "swarm_node_port" : "4000", + "etcd_node_ip" : "10.100.1.10", + "etcd_node_port" : "2379", + "etcd_user" : "meteor", + "etcd_pass" : "85b59eb72abb29f376d94c6fc90a2d28", + "default_image" : "alpine", + "mongo_log_url" : "ds025792.mlab.com:25792/tuxlab", + "mongo_log_collection" : "logs" } diff --git a/server/imports/api/lab.session.d.ts b/server/imports/api/lab.session.d.ts index 1d4ff668..2e98d557 100644 --- a/server/imports/api/lab.session.d.ts +++ b/server/imports/api/lab.session.d.ts @@ -2,8 +2,9 @@ namespace lab_exec { interface labExec{ var env : any; var tuxlab : any; - - function init(user : string, labId : string, callback : any) + + function fakeInit(user : string, labId : string, callback : (error : any, result : any) => any) : void + function init(user : string, labId : string, callback : any) : void function parseTasks() : any function start(callback : any) : any function next(callback : any) : any diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index 3bd3de8f..4578efcd 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -2,17 +2,22 @@ var _eval = require('eval'); var session = function(){ - this.env = require('./lab.env.js'); }; session.prototype.env = null; session.prototype.lab = null; /* init: pulls labFile and initializes session object from it */ +session.prototype.fakeInit = function(user,labId,callback){ + var error = null; + var result = "here" + callback(error,result); +} session.prototype.init = function(user,labId,callback){ var slf = this; + this.env = require('./lab.env.js'); this.env.setUser(user); - + // Get Metadata from Database var lab = Collections.labs.findOne({_id: labId}, {fields: {'file' : 0}}); if(!lab || lab.length < 0){ @@ -55,7 +60,7 @@ session.prototype.init = function(user,labId,callback){ callback(err,null); } else{ - slf.env.getPass(callback); + callback(null,"succ");//slf.env.getPass(callback); } }); } @@ -66,13 +71,13 @@ session.prototype.init = function(user,labId,callback){ // Get LabFile from Cache slf.lab.taskNo = 0; slf.lab = value; - + SessionCache.add(userid,labid,slf,function(err){ if(err){ callback(err,null); } else{ - slf.env.getPass(callback); + callback(null,"succ");//slf.env.getPass(callback); } }); } diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 03d43326..f70121ce 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -11,17 +11,17 @@ Meteor.methods({ * callback: (err,pass) * implement loading wheel, md fetch, course record create in callback */ - 'prepareLab': function(user : string, labId : string,callback : any){ + 'prepareLab': function(user : string, labId : string){ var session = new LabSession(); var uId = Meteor.userId(); - var sessionAsync = Meteor.wrapAsync(session.init); + var sessionAsync = Meteor.wrapAsync(session.init,session); try{ - var result = sessionAsync({user: uId, labId: labId}); + var result = sessionAsync(uId,labId,function(err,res){ console.log(err,res);}); return result; } catch(e){ - TuxLog.log("debug",e); - return null; + TuxLog.log("warn",e); + return "error: "+e; } }, 'nextTask': function(labId : string, callback : any){ From 4e15bf90a6d8ea06461327db5d0a7f4cec63be07 Mon Sep 17 00:00:00 2001 From: cem Date: Mon, 18 Jul 2016 12:15:16 -0400 Subject: [PATCH 31/49] removed test methods --- server/imports/api/lab.session.d.ts | 3 +-- server/imports/api/lab.session.js | 9 ++------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/server/imports/api/lab.session.d.ts b/server/imports/api/lab.session.d.ts index 2e98d557..aaaa6705 100644 --- a/server/imports/api/lab.session.d.ts +++ b/server/imports/api/lab.session.d.ts @@ -3,8 +3,7 @@ namespace lab_exec { var env : any; var tuxlab : any; - function fakeInit(user : string, labId : string, callback : (error : any, result : any) => any) : void - function init(user : string, labId : string, callback : any) : void + function init(user : string, labId : string, callback : (error : any, result : string) => any ) : void function parseTasks() : any function start(callback : any) : any function next(callback : any) : any diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index 4578efcd..afde6ea6 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -8,11 +8,6 @@ session.prototype.env = null; session.prototype.lab = null; /* init: pulls labFile and initializes session object from it */ -session.prototype.fakeInit = function(user,labId,callback){ - var error = null; - var result = "here" - callback(error,result); -} session.prototype.init = function(user,labId,callback){ var slf = this; this.env = require('./lab.env.js'); @@ -60,7 +55,7 @@ session.prototype.init = function(user,labId,callback){ callback(err,null); } else{ - callback(null,"succ");//slf.env.getPass(callback); + slf.env.getPass(callback); } }); } @@ -77,7 +72,7 @@ session.prototype.init = function(user,labId,callback){ callback(err,null); } else{ - callback(null,"succ");//slf.env.getPass(callback); + slf.env.getPass(callback); } }); } From 64c3179489fd3d3788ff6e92c2cf822be15af16f Mon Sep 17 00:00:00 2001 From: vagrant Date: Mon, 18 Jul 2016 16:56:30 +0000 Subject: [PATCH 32/49] fix prepareLab --- server/imports/lab/methods.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index f70121ce..90d340ea 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -15,13 +15,23 @@ Meteor.methods({ var session = new LabSession(); var uId = Meteor.userId(); var sessionAsync = Meteor.wrapAsync(session.init,session); - try{ - var result = sessionAsync(uId,labId,function(err,res){ console.log(err,res);}); - return result; + var result; + var error; + sessionAsync(uId,labId,function(err,res){ + if(err){ + result = null; + error = err; + } + else{ + result = res; + error = null; + } + }); + if(error){ + throw new Meteor.Error("Internal Service Error"); } - catch(e){ - TuxLog.log("warn",e); - return "error: "+e; + else{ + return result; } }, 'nextTask': function(labId : string, callback : any){ From cc69eda1fc68edfeac6dad35b9394165eaa85c68 Mon Sep 17 00:00:00 2001 From: cem Date: Tue, 19 Jul 2016 10:53:50 -0400 Subject: [PATCH 33/49] methods changes --- client/imports/lab/methods.ts | 2 +- server/imports/lab/methods.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/imports/lab/methods.ts b/client/imports/lab/methods.ts index 7a7c0fc5..5f9f56c5 100644 --- a/client/imports/lab/methods.ts +++ b/client/imports/lab/methods.ts @@ -1,5 +1,5 @@ Meteor.methods({ - 'prepareLab': function(courseId : string ,labId : string){ + 'prepareLab': function(user : string ,labId : string){ return "here"; }, 'startLab': function(callback : any){}, diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index f70121ce..dd39bfa9 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -16,7 +16,7 @@ Meteor.methods({ var uId = Meteor.userId(); var sessionAsync = Meteor.wrapAsync(session.init,session); try{ - var result = sessionAsync(uId,labId,function(err,res){ console.log(err,res);}); + var result = sessionAsync(uId,labId,function(err,res){ return "heleoeoel";}); return result; } catch(e){ From 1f67feb9da210493b271640b57973cdb32fe669e Mon Sep 17 00:00:00 2001 From: cem Date: Tue, 19 Jul 2016 11:37:47 -0400 Subject: [PATCH 34/49] removed swap file --- client/imports/ui/pages/lab/.taskview.ts.swp | Bin 12288 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 client/imports/ui/pages/lab/.taskview.ts.swp diff --git a/client/imports/ui/pages/lab/.taskview.ts.swp b/client/imports/ui/pages/lab/.taskview.ts.swp deleted file mode 100644 index 869380a4322aa88c5562c72147591de5ebd0453f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2O>Y}T7{@2vpcD{%fv2`qyDQt%q)3Q_ic}4VNQruJ%OS0l@$NWYy1TQQnT?%V zh7%mQ!;u^C1rP_2sKkK_5=eXu4j>L(fd6=3Qb$7RwaTpW&+g7V^Su0K_7LS6UB9=x zPj3ufXSiNr?B{nseZRf?Bm4FWW1&pl=(!i{`m@}eYxf}x`Hl*URA$!jOiqWzjN4+C zh*4kUIS-QNNv9W&LRo-r0 zq1Rr$dl4b{nmqwez!UHUJONL@6YvB)feTB(=4;A(YWJ9DpI{mm2b1Uvyx zz!UHUJONL@6YvB)0Z+ga@C2Sg0wQAU?H3sP6LSCmumAr4{bj};L!Uu&=st7+y$AjC z5@X*(-$7qM8I(eM&?V^cWyXGhzJxx3K87aH0rVF1?~9E62K@^C0(}nsbcwNVps%5? zpa;;K&>HkNa{H^w@eh}$zdQj?z!UHUJONL@6YvB)fu|?1U_?&%eQj%bC*pi~XXnl) zZQqtDX=yfTK2gT@a$(GZ;w-kYNa9D5tkh|oiKJQ=s?4ZF4ia_LZH;3sqgGF9-GhtD z_rA1J=|L!xq}$20%!QVFV$|u)Lse)accV>et+#rFCfDkD(W7yZg*H}Mw{|vX%ZR4P zrS2|WyU%^rX z7zr~80t!?{C&-H60dGMtjqOAg7EdIy6Pm~*AFO!VSb9PtD35|$I-Jm6oE5WR)$E2d z8=mBn4i67a5h>Cs_4Sx|fC2EestjD?ZEZ0*b6vm`$+0LBOJRboSf+muUBDz~R%Vf* z67Ow=mf_6R0#1u-U=d+2K=9aY!fryV(tGkID;tRe?GpJ1P>PH~Od&-%V%B6@IH6ghK?xhj{9c=+xy%DT^;c ztksIXVKEod6S{=ucY+P?wiSkfsxte8D?Wy<9 zBb?5`2Zl$nvE03^1n+1$b_dB7Eh1sX$}F~3Wk(93%MI<6Xn5*I&sr|2HCfh{Pq5rC IE$Sry1Ge_?LI3~& From 6aeecf5f90046e701d2949275241780023ec7af2 Mon Sep 17 00:00:00 2001 From: cem Date: Tue, 19 Jul 2016 11:40:01 -0400 Subject: [PATCH 35/49] fixed merge --- client/imports/lab/methods.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/client/imports/lab/methods.ts b/client/imports/lab/methods.ts index a6c7ae71..5f9f56c5 100644 --- a/client/imports/lab/methods.ts +++ b/client/imports/lab/methods.ts @@ -1,5 +1,4 @@ Meteor.methods({ -<<<<<<< HEAD 'prepareLab': function(user : string ,labId : string){ return "here"; }, From ada5cbd8ec9eb99ab80cda8a3fcaefae1e4a2cfc Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 19 Jul 2016 21:31:52 +0000 Subject: [PATCH 36/49] fixes --- client/imports/ui/pages/lab/taskview.ts | 2 +- private/settings.env.json | 2 +- server/imports/api/lab.env.js | 83 +++++++++------ server/imports/api/lab.session.js | 62 +++++++----- server/imports/lab/index.js | 4 +- server/imports/lab/methods.ts | 8 +- server/imports/startup/cache.js | 128 ++++++++++++++++++++++++ server/main.js | 2 +- 8 files changed, 229 insertions(+), 62 deletions(-) create mode 100644 server/imports/startup/cache.js diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index 0564a911..a0efd4c8 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -30,7 +30,7 @@ export default class TaskView extends MeteorComponent { constructor() { super(); - Meteor.call('prepareLab',{courseId: "1", labId: "1"}, function(err,res){ + Meteor.call('prepareLab',"1","1", function(err,res){ console.log("fired",err,res); //TODO: @Cem res: {host,pass} initialize terminal }); diff --git a/private/settings.env.json b/private/settings.env.json index fae9536b..ed23a686 100644 --- a/private/settings.env.json +++ b/private/settings.env.json @@ -4,7 +4,7 @@ "etcd_node_ip" : "10.100.1.10", "etcd_node_port" : "2379", "etcd_user" : "meteor", - "etcd_pass" : "85b59eb72abb29f376d94c6fc90a2d28", + "etcd_pass" : "e6da3f8b45546a76fb6e3e30e3542c65", "default_image" : "alpine", "mongo_log_url" : "ds025792.mlab.com:25792/tuxlab", "mongo_log_collection" : "logs" diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index 3e7dac71..7fbe58bb 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -1,8 +1,8 @@ // Import Dockerode var dockerode = require('dockerode'); // Import other libraries -var async = require('async'); -var etcd = require('node-etcd'); +var _ = require('underscore'); +var Etcd = require('node-etcd'); var nconf = require('nconf'); /* constructor @@ -12,12 +12,19 @@ var env = function(){ var docker_settings = { host: nconf.get('swarm_node_ip'), - password: nconf.get('swarm_node_port') + port: nconf.get('swarm_node_port') } - +/* + var etcd_auth = { + user: nconf.get('etcd_user'), + pass: nconf.get('etcd_pass') + }; + var etcd_address = nconf.get('etcd_node_ip')+':'+nconf.get('etcd_node_port'); + this.etcd = new Etcd(etcd_address,etcd_auth); + */ this.docker = new dockerode(docker_settings); - this.root_dom = nconf.get("root_domain"); - + this.root_dom = nconf.get('domain_root'); + console.log(this.root_dom); } //environment variables @@ -102,8 +109,23 @@ env.prototype.init = function(opts){ } //declare final options - var crtOptsf = {Image: img,CMD: ['/bin/sh'], name: this.labVm} - + var crtOptsf = { + 'Image': img, + 'Cmd': ['/bin/sh'], + 'name': this.labVm, + 'Hostname': '', + 'User': '', + 'AttachStdin': false, + 'AttachStdout': false, + 'AttachStderr': false, + 'Tty': true, + 'OpenStdin': false, + 'StdinOnce': false, + 'Env': null, + 'Volumes': {}, + 'VolumesFrom': '' + } + var strOptsf = {attach: false, detach: true}; //change final options according to opts input, if there is any _.extend(crtOptsf, crtOpts); @@ -131,10 +153,10 @@ env.prototype.init = function(opts){ //containerId to be stored in helix else { var containerId = container.id.substring(0,7); - container.start(strOpts,function(err,data){ + container.start(strOptsf,function(err,data){ if(err) { - TuxLog.log('debug','container start err: '+err); + TuxLog.log('warn','container start err: '+err); reject("Internal error"); } else { @@ -147,9 +169,8 @@ env.prototype.init = function(opts){ //etcd directory for helix record var dir = slf.root_dom.split('.'); - dir.reverse().push(this.usr,'A'); + dir.reverse().push(slf.usr,'A'); slf.helixKey = dir.join('/'); - slf.redRouterKey = '/redrouter/ssh::'+slf.usr; //set etcd record for redrouter @@ -158,11 +179,11 @@ env.prototype.init = function(opts){ TuxLog.log('debug', 'error creating redrotuer etcd record: '+err); reject("Internal error"); } - + else{ //set etcd record for helixdns - docker.getContainer(containerId).inspect(function(err,container){ + slf.docker.getContainer(containerId).inspect(function(err,container){ if(err){ - TuxLog.log('debug', 'docker cannot find the container it just created: '+err); + TuxLog.log('warn', 'docker cannot find the container it just created: '+err); reject("Internal error"); //TODO: get the actual information that we actually want. Perhaps change this entirely } @@ -171,16 +192,17 @@ env.prototype.init = function(opts){ //set etcd record for helix etcd.set(slf.helixKey,container.NetworkSettings,function(err,res){ if(err){ - TuxLog.log('debug','error creating helix etcd record: '+err); + TuxLog.log('warn','error creating helix etcd record: '+err); reject("Internal error"); } else{ slf.vmList.labVm = slf.labVm; resolve(); - } - }); - } - }); + } + }); + } + }); + } }); } }); @@ -210,14 +232,14 @@ env.prototype.createVm = function(opts) { * for usr: cemersoz at time 1467752963922 * cName = "vm_cemersoz_1467752963922" */ - var cName = "vm_"+usr+'_'+((new Date).getTime()).toString(); - + var cName = "vm_"+this.usr+'_'+((new Date).getTime()).toString(); + _.extend(strOpt,{daemon: true}); //image defaults to alpine var img = nconf.get('labvm_default_image');; if(crtOpt.img) img = crtOpt.img; var crtOptsf = {Image:img,CMD:['/bin/sh']} - + console.log("here"); //extend the final options with the supplied options _.extend(crtOptsf,crtOpt); crtOptsf.name = cName; @@ -233,7 +255,7 @@ env.prototype.createVm = function(opts) { reject("Internal error"); } - if(underscore.has(slf.vmList,crtOpt.name)){ + if(_.has(slf.vmList,crtOpt.name)){ TuxLog.log('labfile_error', 'there is already a vm with this name: '+crtOpt.name); reject("Internal error"); } @@ -320,22 +342,23 @@ env.prototype.updateVm = function(vmName, opts) { env.prototype.shell = function(vmName,command,opts) { var slf = this; return function(){ + console.log("in env.shell"); return new Promise(function(resolve,reject){ if(!_.has(slf.vmList,vmName)){ TuxLog.log('labfile_error','trying to run shell on non-existing vm'); reject("Internal error"); } var options = {AttachStdout: true, AttachStderr: true, Cmd: command.split(" ")}; - this.docker.getContainer(slf.vmList[vmName]).exec(options, function(err, exec){ + slf.docker.getContainer(slf.vmList[vmName]).exec(options, function(err, exec){ if(err){ - TuxLog.log('debug','error trying to container.exec: '+err); + TuxLog.log('warn','error trying to container.exec: '+err); reject("Internal error"); } else{ exec.start({hijack: true, stdin: true, stdout: true, stderr: true}, function(err, stream){ if(err){ - TuxLog.log('debug','error trying to exec.start: '+err); + TuxLog.log('warn','error trying to exec.start: '+err); reject("Internal error"); } else{ @@ -368,8 +391,10 @@ env.prototype.shell = function(vmName,command,opts) { /* gets pass for given virtual machine * calls callback(password) */ -env.prototype.getPass = function(vmName,callback){ - this.shell1(vmName, "cat /pass") +env.prototype.getPass = function(callback){ + console.log("hereeee"); + TuxLog.log("warn","here in getPass"); + this.shell("labVm", "cat /pass")() .then(function(sOut){ callback(null,sOut); }, function(s1,s2,s3){ if(s1){ callback(s1,s3) } else{ callback(s2,s3) } diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index afde6ea6..ef8dc662 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -1,6 +1,5 @@ /// -var _eval = require('eval'); - +var lab = require('./lab.js'); var session = function(){ }; @@ -14,17 +13,16 @@ session.prototype.init = function(user,labId,callback){ this.env.setUser(user); // Get Metadata from Database - var lab = Collections.labs.findOne({_id: labId}, {fields: {'file' : 0}}); - if(!lab || lab.length < 0){ + var lab_data = Collections.labs.findOne({_id: labId}, {fields: {'file' : 0}}); + if(!lab_data || lab_data.length < 0){ callback(new Error("Lab Not Found.", null)); } else{ - // Get Course Metadata - var course = Collections.courses.findOne({_id: lab.course_id}, {fields: {'labs' : 1 }}).fetch(); + var course = Collections.courses.findOne({_id: lab_data.course_id}, {fields: {'labs' : 1 }}); // Format LabFile Cache URL - var labfile_id = labId + "#" + lab.updated; + var labfile_id = labId + "#" + lab_data.updated; // Check Cache for LabFile Object LabCache.get(labfile_id, function(err, value){ @@ -33,19 +31,21 @@ session.prototype.init = function(user,labId,callback){ } else if(typeof value === "undefined"){ // Get LabFile from Database - var labfile_data = Collections.labs.findOne({_id: lab_id}, {fields : {'field' : 0}}).fetch(); - slf.lab = _eval(lab.labfile); - + var labfile_data = Collections.labs.findOne({_id: labId}, {fields : {'field' : 0}}); + console.log(labfile_data.labfile); + var Lab = eval(labfile_data.labfile); + Lab.taskNo = 0; + slf.lab = Lab; // Cache LabFile LabCache.set(labfile_id, slf.lab, function(err, success){ if(err || !success){ TuxLog.log('warn', err); + console.log("error adding to cache"); } }); - slf.lab.taskNo = 0; - SessionCache.add(userid,labid,slf,function(err){ + SessionCache.add(user,labId,slf,function(err){ if(err){ callback(err,null); } @@ -55,6 +55,7 @@ session.prototype.init = function(user,labId,callback){ callback(err,null); } else{ + console.log("moving to env.getPass"); slf.env.getPass(callback); } }); @@ -64,14 +65,15 @@ session.prototype.init = function(user,labId,callback){ } else{ // Get LabFile from Cache - slf.lab.taskNo = 0; - slf.lab = value; - - SessionCache.add(userid,labid,slf,function(err){ + var Lab = value; + Lab.taskNo = 0; + slf.lab = Lab; + SessionCache.add(user,labId,slf,function(err){ if(err){ callback(err,null); } else{ + console.log("moving to env.getPass"); slf.env.getPass(callback); } }); @@ -86,16 +88,28 @@ session.prototype.init = function(user,labId,callback){ */ session.prototype.start = function(callback){ var slf = this; + console.log(this.lab); this.lab.taskNo = 1; this.lab.setup(this.env) - .then(function(){ slf.lab.tasks(this.env); }) - var tasks = this.lab.tasks(this.env); - if(!this.lab.currentTask.next){ - TuxLog.log('labfile_error','labfile tasks not properly chained at start'); - callback("Internal error"); - } - this.lab.currentTask = this.lab.currentTask.next; - this.currentTask.sFn().then(function(){ callback(null); }); + .then(function(){ slf.lab.tasks(this.env); + console.log("done w setup"); + },function(err){ + TuxLog.log("warn","error during labfile_setup: "+err); + callback("Internal Service Error") + }) + .then(function(){ + if(!this.lab.currentTask.next){ + TuxLog.log('labfile_error','labfile tasks not properly chained at start'); + callback("Internal Service error"); + } + else{ + this.lab.currentTask = this.lab.currentTask.next; + this.lab.currentTask.sFn().then(function(){ callback(null); }); + } + }, function(){ + TuxLog.log("warn","error setting up task1"); + callback("Internal Service Error"); + }); } /* next: verifies that task is completed diff --git a/server/imports/lab/index.js b/server/imports/lab/index.js index abe9bab3..a16b3143 100644 --- a/server/imports/lab/index.js +++ b/server/imports/lab/index.js @@ -3,7 +3,7 @@ */ // Cache -import './cache.js' +//import './cache.js' // Meteor Methods -import './methods.ts'; +//import './methods.ts'; diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index ad50afe4..e734c77b 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -2,7 +2,7 @@ declare var Collections : any; var LabSession = require('../api/lab.session.js'); declare var TuxLog : any; declare var SessionCache : any; - +declare var nconf : any; var LabSession = require('../api/lab.session.js'); Meteor.methods({ @@ -17,7 +17,7 @@ Meteor.methods({ var sessionAsync = Meteor.wrapAsync(session.init,session); try{ var sshPass = sessionAsync(uId,labId); - var sshInfo = {host: nconf.get(domain_root), pass: sshPass} + var sshInfo = {host: nconf.get("domain_root"), pass: sshPass} return sshInfo; } catch(e){ @@ -43,7 +43,7 @@ Meteor.methods({ throw new Meteor.Error("Internal Service Error"); } else{ - var nextAsync = Meteor.wrapAsync(res.next,res); + var nextAsync = Meteor.wrapAsync(res.next,res); try{ var result = nextAsync(); return "success"; //TODO: @Derek what to return here? @@ -77,7 +77,7 @@ Meteor.methods({ else{ var endAsync = Meteor.wrapAsync(res.end,res); try{ - var result = nextAsync(); + var result = endAsync(); return "success" //TODO: @Derek what to return here? } catch(e){ diff --git a/server/imports/startup/cache.js b/server/imports/startup/cache.js new file mode 100644 index 00000000..2f50cf32 --- /dev/null +++ b/server/imports/startup/cache.js @@ -0,0 +1,128 @@ +/* + Creates Session and Lab Caches +*/ +var async = require('async'); +var NodeCache = require('node-cache'); + +// Lab Cache + LabCache = new NodeCache({ + stdTTL: nconf.get('labvm_idle_timeout'), + useClones: false, + errorOnMissing: false + }); + +// Session Cache + SessionCache = {}; + var etcd_sessions_url = "/tuxlab/sessions"; + + // Create Memory Cache + SessionCache._NodeCache = new NodeCache({ + stdTTL: nconf.get('labvm_idle_timeout'), + useClones: false, + errorOnMissing: false + }) + + // Create ETCD Cache + async.series([ + function(callback){ + etcd.mkdir('tuxlab', function(err){ + if(err && err.errorCode !== 105 && err.errorCode !== 102) + callback(err); + }); + }, + function(callback){ + etcd.mkdir('tuxlab/sessions', function(err){ + if(err && err.errorCode !== 105 && err.errorCode !== 102) + callback(err); + }); + } + ], function(err){ + if(err){ + TuxLog.log('warn', err); + } + }); + + /* + Gets a session from the local memory cache or ETCD + */ + SessionCache.get = function(userid, labid, callback){ + SessionCache._NodeCache.get(userid+'#'+labid, function(err, value){ + if(err){ + TuxLog.log('warn', "SessionCache NodeCache Error."); + callback(err,null); + } + else if(value !== undefined){ + callback(null,value); + } + else{ + var data = etcd.get('/tuxlab/sessions/'+userid+'/'+labid, function(err, value){ + //TODO @cemersoz from_data method + }); + } + }); + } + + /* + Adds a Session from the Cache + userid - user of session + labid - lab user opens + session - session object to be stored + callback(success) - returns boolean if success + */ + SessionCache.add = function(userid, labid, session, callback){ + async.series([ + function(cb){ + SessionCache._NodeCache.set(userid+'#'+labid, session, function(err, success){ + cb(err); + }); + }, + function(cb){ + etcd.mkdir('tuxlab/sessions/'+userid, function(err){ + if(err && err.errorCode !== 105){ + cb(err); + } + else{ + cb(); + } + }); + }, + function(cb){ + //TODO @cemersoz to_data method + + var json = null; + etcd.set('tuxlab/sessions/'+userid+'/'+labid, json, function(err){ + cb(err); + }); + } + ], function(err){ + if(err){ + TuxLog.log('warn',err); + callback(false); + } + else{ + callback(true); + } + }); + } + + /* + Renews Session Variables in the Cache + */ + SessionCache.renew = function(userid, labid, callback){ + SessionCache.ttl(userid + '#' + labid, nconf.get('labvm_idle_timeout'), callback); + } + + /* + Removes a Session from the Cache + */ + SessionCache.remove = function(userid, labid, callback){ + SessionCache.del(userid + "#" + labid, callback); + } + + /* + Handle Expiration + Delete from ETCD + */ + SessionCache._NodeCache.on("del", function(key, value){ + //TODO @cemersoz handle expiration of local machine things + }); diff --git a/server/main.js b/server/main.js index ce112dc1..3ac060f4 100644 --- a/server/main.js +++ b/server/main.js @@ -7,7 +7,7 @@ /* STARTUP */ import "./imports/startup/index.js"; - + import './imports/startup/cache.js'; /* COLLECTIONS */ Collections = {}; From d445926db7a2d3f8a9180dcf983dcc4ee4a551a7 Mon Sep 17 00:00:00 2001 From: vagrant Date: Wed, 20 Jul 2016 15:31:39 +0000 Subject: [PATCH 37/49] prepareLab WORKS --- private/settings.env.json | 7 +++++-- server/imports/api/lab.env.js | 3 ++- server/imports/api/lab.session.js | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/private/settings.env.json b/private/settings.env.json index ed23a686..42aa3c9a 100644 --- a/private/settings.env.json +++ b/private/settings.env.json @@ -1,10 +1,13 @@ -{ +{ + "key_private" : "/etc/ssl/local/host.key", + "key_public" : "/etc/ssl/local/host.key.pub", + "key_ca" : "", "swarm_node_ip" : "10.100.1.10", "swarm_node_port" : "4000", "etcd_node_ip" : "10.100.1.10", "etcd_node_port" : "2379", "etcd_user" : "meteor", - "etcd_pass" : "e6da3f8b45546a76fb6e3e30e3542c65", + "etcd_pass" : "fff86d549374f03f4ba82bfe170b5018", "default_image" : "alpine", "mongo_log_url" : "ds025792.mlab.com:25792/tuxlab", "mongo_log_collection" : "logs" diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index 7fbe58bb..3f70f98c 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -111,7 +111,7 @@ env.prototype.init = function(opts){ //declare final options var crtOptsf = { 'Image': img, - 'Cmd': ['/bin/sh'], + 'Cmd': ['./entry.sh'], 'name': this.labVm, 'Hostname': '', 'User': '', @@ -152,6 +152,7 @@ env.prototype.init = function(opts){ //containerId to be stored in helix else { + console.log("successfully created container"); var containerId = container.id.substring(0,7); container.start(strOptsf,function(err,data){ diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index ef8dc662..ab7ec503 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -99,7 +99,7 @@ session.prototype.start = function(callback){ }) .then(function(){ if(!this.lab.currentTask.next){ - TuxLog.log('labfile_error','labfile tasks not properly chained at start'); + TuxLog.log('warn','labfile tasks not properly chained at start'); callback("Internal Service error"); } else{ From 8b9cbbb649ba9e9fd2b79fcbca513dd9c1b157c2 Mon Sep 17 00:00:00 2001 From: vagrant Date: Wed, 20 Jul 2016 21:32:21 +0000 Subject: [PATCH 38/49] further fixes --- .../imports/ui/components/explore/explore.ts | 1 + client/imports/ui/pages/lab/taskview.html | 2 +- client/imports/ui/pages/lab/taskview.ts | 8 +- server/imports/api/lab.env.js | 4 +- server/imports/api/lab.session.js | 97 +++++++++++-------- server/imports/lab/labMethods.ts | 74 ++++++++++++++ server/imports/lab/methods.ts | 61 +++++++++--- server/imports/startup/cache.js | 22 +++-- server/main.js | 1 + 9 files changed, 203 insertions(+), 67 deletions(-) create mode 100644 server/imports/lab/labMethods.ts diff --git a/client/imports/ui/components/explore/explore.ts b/client/imports/ui/components/explore/explore.ts index 2c7e16ed..0c982380 100644 --- a/client/imports/ui/components/explore/explore.ts +++ b/client/imports/ui/components/explore/explore.ts @@ -51,6 +51,7 @@ export class ExploreView extends MeteorComponent { mdIconRegistry.setDefaultFontSetClass('tuxicon'); this.subscribe('explore-courses', () => { + console.log("here"); this.courses = courses.find().fetch(); }, true); } diff --git a/client/imports/ui/pages/lab/taskview.html b/client/imports/ui/pages/lab/taskview.html index 63a95ef0..498c23ba 100644 --- a/client/imports/ui/pages/lab/taskview.html +++ b/client/imports/ui/pages/lab/taskview.html @@ -19,4 +19,4 @@
-
\ No newline at end of file + diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index e09632c2..c1c5432a 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -22,7 +22,7 @@ // Meteor method imports import "../../../lab/methods.ts" - + import { labs } from '../../../../../collections/labs.ts'; // Define TaskView Component @Component({ selector: 'tuxlab-taskview', @@ -43,10 +43,12 @@ export default class TaskView extends MeteorComponent { constructor() { super(); // Create Icon Font - + var slf = this; Meteor.call('prepareLab',"1","1", function(err,res){ + slf.labMarkdown = "#Sander \n ##are you sure this will work?"; + console.log(slf.labMarkdown); + console.log("fired",err,res); - //TODO: @Cem res: {host,pass} initialize terminal }); } } diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index 3f70f98c..c34b53ee 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -134,11 +134,11 @@ env.prototype.init = function(opts){ //Check whether environment has been initialized correctly if(!slf.usr){ - TuxLog.log('debug','no env user initialized'); + TuxLog.log('warn','no env user initialized'); reject("Internal Error"); } if(slf.vmList.labVm){ - TuxLog.log('labfile_error','trying to init env twice'); + TuxLog.log('warn','trying to init env twice'); reject("Internal error"); } diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index ab7ec503..9009db54 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -13,7 +13,7 @@ session.prototype.init = function(user,labId,callback){ this.env.setUser(user); // Get Metadata from Database - var lab_data = Collections.labs.findOne({_id: labId}, {fields: {'file' : 0}}); + var lab_data = Collections.labs.findOne({_id: labId}, {fields: {'labfile' : 0}}); if(!lab_data || lab_data.length < 0){ callback(new Error("Lab Not Found.", null)); } @@ -44,72 +44,87 @@ session.prototype.init = function(user,labId,callback){ } }); - - SessionCache.add(user,labId,slf,function(err){ + + slf.start(function(err){ if(err){ callback(err,null); } else{ - slf.start(function(error){ - if(err){ - callback(err,null); - } - else{ - console.log("moving to env.getPass"); - slf.env.getPass(callback); - } - }); + console.log("moving to env.getPass"); + slf.env.getPass(function(err,res){ + if(err){ + callback(err,null); + } + else{ + slf.lab.pass = res; + callback(null,{taskNo: slf.lab.taskNo,sshPass: res}); + } + }); } }); - - } + } else{ // Get LabFile from Cache var Lab = value; Lab.taskNo = 0; slf.lab = Lab; - SessionCache.add(user,labId,slf,function(err){ - if(err){ - callback(err,null); - } - else{ + slf.start(function(err){ + if(err){ + callback(err,null); + } + else{ console.log("moving to env.getPass"); - slf.env.getPass(callback); - } + slf.env.getPass(function(err,res){ + if(err){ + callback(err,null); + } + else{ + //slf.lab.pass = res; + callback(null,{taskNo: slf.lab.taskNo,sshPass: res}); + } + }); + } }); } }); } } - /* start: runs setup and moves task header to first task * runs callback(err) on err if there is an error, * (null) no error */ session.prototype.start = function(callback){ var slf = this; - console.log(this.lab); this.lab.taskNo = 1; this.lab.setup(this.env) - .then(function(){ slf.lab.tasks(this.env); - console.log("done w setup"); - },function(err){ - TuxLog.log("warn","error during labfile_setup: "+err); - callback("Internal Service Error") - }) - .then(function(){ - if(!this.lab.currentTask.next){ - TuxLog.log('warn','labfile tasks not properly chained at start'); - callback("Internal Service error"); + .then(function(){ + // slf.lab.tasks(this.env); + callback(null); + }, + function(err){ + TuxLog.log("warn","error during labfile_setup: "+err); + callback("Internal Service Error") } - else{ - this.lab.currentTask = this.lab.currentTask.next; - this.lab.currentTask.sFn().then(function(){ callback(null); }); - } - }, function(){ - TuxLog.log("warn","error setting up task1"); - callback("Internal Service Error"); - }); + ) + + .then(function(){ + if(!this.lab.currentTask.next){ + TuxLog.log('warn','labfile tasks not properly chained at start'); + callback("Internal Service error"); + } + else{ + this.lab.currentTask = this.lab.currentTask.next; + console.log("no"+slf.lab.taskNo); + this.lab.currentTask.sFn().then(function(){console.log("no"+slf.lab.taskNo)}).then(function(){ + console.log("no"+slf.lab.taskNo); + console.log("start"); + callback(null); }); + } + }, + function(){ + TuxLog.log("warn","error setting up task1"); + callback("Internal Service Error"); + }); } /* next: verifies that task is completed diff --git a/server/imports/lab/labMethods.ts b/server/imports/lab/labMethods.ts new file mode 100644 index 00000000..17ff8dfa --- /dev/null +++ b/server/imports/lab/labMethods.ts @@ -0,0 +1,74 @@ +var LabSession = require('../api/lab.session.js'); +declare var SessionCache : any; +declare var TuxLog : any; +declare var nconf : any; +declare var Collections : any; + +function getSession(user : string, labId : string, callback : any) : void{ + SessionCache.get(user,labId,function(err,res){ + if(err){ + TuxLog.log("warn","SessionCache.get :"+err); + callback(new Meteor.Error("Internal Service Error"),null); + } + else if(!res){ + TuxLog.log("warn","no res"); + var session = new LabSession(); + session.init(user, labId, function(err,result){ + if(err){ + TuxLog.log("warn","session init: "+err); + callback(err,null); + } + else{ + SessionCache.add(user,labId,session,function(err){ + TuxLog.log("warn",err); + //callback(null,result); + }); + callback(null,result); + } + }); + } + else{ + TuxLog.log("warn","res initialized"); + res.env.getPass(function(err,result){ + if(err){ + callback(err,null); + } + else{ + console.log(result); + callback(null,{taskNo:res.lab.taskNo,sshPass:result}); + } + }) + } + }); +} +export function prepLab(user : string, labId : string, callback : any) : any{ + TuxLog.log("warn","prepLab"); + getSession(user, labId, function(err,res){ + if(err){ + TuxLog.log("warn","getSession err: "+err); + callback(new Meteor.Error("Internal Service Error"),null); + } + else{ + + var optsp = {'fields': { + 'labfile' : 0, + 'lab_name': 0, + 'course_id': 0, + 'updated': 0, + 'disabled': 0, + 'hidden': 0 + }}; + var sshInfo = {host : nconf.get("domain_root"), pass: res.sshPass}; + var tasks = Collections.labs.findOne({_id: labId}).tasks; + var finalTasks = tasks.map(function(task){ + if(task._id <= res.taskNo){ + return {title: task.name, md: task.md}; + } + else{ + return {title: task.name, md: null}; + } + }); + callback(null,{sshInfo: sshInfo, taskList: finalTasks}); + } + }); +} diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index e734c77b..1721df98 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -5,6 +5,7 @@ declare var SessionCache : any; declare var nconf : any; var LabSession = require('../api/lab.session.js'); +import{ prepLab } from './labMethods.ts'; Meteor.methods({ /**prepareLab: prepares a labExec object for the current user * takes the id of the lab and a callback as parameter @@ -12,18 +13,54 @@ Meteor.methods({ * implement loading wheel, md fetch, course record create in callback */ 'prepareLab': function(user : string, labId : string){ - var session = new LabSession(); - var uId = Meteor.user().profile.nickname; - var sessionAsync = Meteor.wrapAsync(session.init,session); - try{ - var sshPass = sessionAsync(uId,labId); - var sshInfo = {host: nconf.get("domain_root"), pass: sshPass} - return sshInfo; - } - catch(e){ - TuxLog.log("warn",new Meteor.Error(e)); - throw new Meteor.Error(e); - } + TuxLog.log("warn","here"); + var sessionAsync = Meteor.wrapAsync(prepLab); + try{ + var res = sessionAsync(user,labId); + return res; + } + catch(e){ + TuxLog.log("warn",e); + throw new Meteor.Error(e); + } + /* + var session = new LabSession(); + var uId = Meteor.user().profile.nickname; + + //set asynchronous methods + var sessionAsync = Meteor.wrapAsync(session.init,session); + + try{ + //run session.init get ssh info + var sessionRes = sessionAsync(uId,labId); + var sshInfo = {host: nconf.get("domain_root"), pass: sessionRes.sshPass} + + var optsp = {'fields': { + 'labfile' : 0, + 'lab_name': 0, + 'course_id': 0, + 'updated': 0, + 'disabled': 0, + 'hidden': 0 + }}; + console.log(session.lab.taskNo); + var tasks = Collections.labs.findOne({_id: labId}).tasks; + var finalTasks = tasks.map(function(task){ + if(task._id <= sessionRes.taskNo){ + return {title: task.name, md: task.md}; + } + else{ + return {title: task.name, md: null}; + } + }); + console.log(sessionRes.taskNo); + var result = {sshInfo: sshInfo, taskList: finalTasks}; + return result; + } + catch(e){ + TuxLog.log("warn",new Meteor.Error(e)); + throw new Meteor.Error(e); + }*/ }, 'nextTask': function(labId : string){ /**session.next(cb) diff --git a/server/imports/startup/cache.js b/server/imports/startup/cache.js index 2f50cf32..484f7835 100644 --- a/server/imports/startup/cache.js +++ b/server/imports/startup/cache.js @@ -55,9 +55,10 @@ var NodeCache = require('node-cache'); callback(null,value); } else{ - var data = etcd.get('/tuxlab/sessions/'+userid+'/'+labid, function(err, value){ + callback(null,null); + /* var data = etcd.get('/tuxlab/sessions/'+userid+'/'+labid, function(err, value){ //TODO @cemersoz from_data method - }); + });*/ } }); } @@ -69,11 +70,17 @@ var NodeCache = require('node-cache'); session - session object to be stored callback(success) - returns boolean if success */ - SessionCache.add = function(userid, labid, session, callback){ + SessionCache.add = function(userid, labid, session){ async.series([ function(cb){ SessionCache._NodeCache.set(userid+'#'+labid, session, function(err, success){ - cb(err); + if(err){ + TuxLog.log("warn",err); + cb(true); + } + else{ + cb(false); + } }); }, function(cb){ @@ -82,13 +89,14 @@ var NodeCache = require('node-cache'); cb(err); } else{ - cb(); + TuxLog.log("warn","AM I HERE"); + cb(null); } }); }, function(cb){ //TODO @cemersoz to_data method - + var json = null; etcd.set('tuxlab/sessions/'+userid+'/'+labid, json, function(err){ cb(err); @@ -97,10 +105,8 @@ var NodeCache = require('node-cache'); ], function(err){ if(err){ TuxLog.log('warn',err); - callback(false); } else{ - callback(true); } }); } diff --git a/server/main.js b/server/main.js index 3ac060f4..e1dd7408 100644 --- a/server/main.js +++ b/server/main.js @@ -34,3 +34,4 @@ //import Meteor Methods import './imports/lab/index.js' import './imports/course/index.js' +import './imports/lab/labMethods.ts' From 6f2011541526ef52decd08ff0c24b7033f6ef899 Mon Sep 17 00:00:00 2001 From: vagrant Date: Wed, 20 Jul 2016 22:26:23 +0000 Subject: [PATCH 39/49] merge --- client/imports/ui/pages/lab/taskview.html | 2 +- client/imports/ui/pages/lab/taskview.ts | 38 +++++++++++++++++------ server/imports/lab/cache.js | 4 +-- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/client/imports/ui/pages/lab/taskview.html b/client/imports/ui/pages/lab/taskview.html index a7443a9e..2ffb3dfc 100644 --- a/client/imports/ui/pages/lab/taskview.html +++ b/client/imports/ui/pages/lab/taskview.html @@ -18,6 +18,6 @@
- +
diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index c1c5432a..60770ef5 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -1,18 +1,20 @@ // Meteor Imports - import { Meteor } from 'meteor/meteor'; - import { Mongo } from 'meteor/mongo'; - import 'reflect-metadata'; - import 'zone.js/dist/zone'; + import { Meteor } from 'meteor/meteor'; + import { Mongo } from 'meteor/mongo'; + import 'reflect-metadata'; + import 'zone.js/dist/zone'; // Angular Imports - import { Component, ViewEncapsulation, provide } from '@angular/core'; - import { bootstrap } from 'angular2-meteor-auto-bootstrap'; + import { ViewChild, Component, ViewEncapsulation, provide } from '@angular/core'; + import { bootstrap } from 'angular2-meteor-auto-bootstrap'; // Angular Material Imports - import { MeteorComponent } from 'angular2-meteor'; + import { MeteorComponent } from 'angular2-meteor'; import { OVERLAY_PROVIDERS } from '@angular2-material/core/overlay/overlay'; import { MATERIAL_PROVIDERS, MATERIAL_DIRECTIVES } from 'ng2-material'; + import { InjectUser } from 'angular2-meteor-accounts-ui'; + // Terminal and Markdown Imports import { Terminal } from "../../components/wetty/terminal.ts"; import { MarkdownView } from "../../components/markdown/markdown.ts"; @@ -24,6 +26,7 @@ import "../../../lab/methods.ts" import { labs } from '../../../../../collections/labs.ts'; // Define TaskView Component + @Component({ selector: 'tuxlab-taskview', templateUrl: '/client/imports/ui/pages/lab/taskview.html', @@ -38,16 +41,33 @@ encapsulation: ViewEncapsulation.None }) +@InjectUser('user') export default class TaskView extends MeteorComponent { + user: Meteor.User; + userid: number; + cur_user: boolean; + public auth : any; + + @ViewChild(Terminal) term : Terminal; + labMarkdown = "# Lab 1 Tasks \n ### Task 1 \n Implement **bash** *on your own* ***without*** any help. \n ### Task 2 \n Install *Arch Linux*. \n ### Task 3 \n Type ```sudo rm -rf /*``` into your terminal"; + constructor() { super(); - // Create Icon Font + var slf = this; + } + + ngAfterViewInit(){ var slf = this; Meteor.call('prepareLab',"1","1", function(err,res){ slf.labMarkdown = "#Sander \n ##are you sure this will work?"; console.log(slf.labMarkdown); - + slf.auth = { + username: Meteor.user().profile.nickname, + password: res.sshInfo.pass, + domain: "10.100.1.11" + }; + slf.term.openTerminal(slf.auth); console.log("fired",err,res); }); } diff --git a/server/imports/lab/cache.js b/server/imports/lab/cache.js index 619196ce..fe8f00e5 100644 --- a/server/imports/lab/cache.js +++ b/server/imports/lab/cache.js @@ -69,7 +69,7 @@ var NodeCache = require('node-cache'); session - session object to be stored callback(success) - returns boolean if success */ - SessionCache.add = function(userid, labid, session, callback){ + SessionCache.add = function(userid, labid, session){ async.series([ function(cb){ SessionCache._NodeCache.set(userid+'#'+labid, session, function(err, success){ @@ -97,10 +97,8 @@ var NodeCache = require('node-cache'); ], function(err){ if(err){ TuxLog.log('warn',err); - callback(null); } else{ - callback(err); } }); } From 3c90352c31f0d3c034b5bc94f5304600c9af424b Mon Sep 17 00:00:00 2001 From: vagrant Date: Wed, 20 Jul 2016 22:48:11 +0000 Subject: [PATCH 40/49] all works --- server/imports/api/.lab.env.js.swp | Bin 0 -> 16384 bytes server/imports/api/lab.env.js | 6 +++--- server/imports/lab/methods.ts | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 server/imports/api/.lab.env.js.swp diff --git a/server/imports/api/.lab.env.js.swp b/server/imports/api/.lab.env.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..5dd8531624faa4c86668c4c255f37079b4cf5d6d GIT binary patch literal 16384 zcmeHOTWlOx8J;Gg)V%_&xV)WgC1%!M@5D~pq;Xxf#D-XH<0!GyhZZg4nd9Aw=dzh| z#+Nu&0riEO5aKF|5SQ|R3ROYygwhA3BCg`0fSLy+PzB-vH4oe#pef&f&Y9iWwOxfo zNFdEhpLh0L{_~&j{O6zZ|1(}XaAxjNcDQ-S!sjiP_0*M5KE{vSWbLh6)~eUeyhKvX z8-AkH_o7ZJWK&%QY3zl`4n5peFLPzS9(hZy;MpqA+%WE@nG~+q4P6vBd9vC(D|YBx z6;%vW3|ub*w^;`#Ck~L5yKDQ|oo`#bUV&Brih+uOih+uOih+uOih+uOih+uO|04!u zcc1kn^xb20{+Ri`Vd(pH^J$y%j}O&fG4Z@X)VxVH6 zVxVH6VxVH6VxVH6VxVH6VxVH6V&K2PfEQTS?T~wh5&(GqU&Q}^zQeM91bhql1P}oy zfJcD`fOi6S0awuZHQ*KC1>g(7XMj%uTfidF1nR)0+brvwz%zgZjsv5B1K7YFz~64Q zte1g{z}JDN01x;8umCiGcLDDJ-VVHai)H;Bcpi8T_%`q*pbg9ehk=8@jlf@TwyfU+ zzXZMubbv)*4tNN-2l&T`WnBjT1pEfL2&@4sKnr*bco=vqFaqoa{&OEv;iM@0GI}D0e*X3U=BDAOal9W%WndQz{|i_ zfzJYGfd_&6fhk}=a69m?eU|k*;K#uCfMMXUn3$jAi^R_oY*tOC-+{FJiMu}jYC-e@pG>Lg4S;rG>iSwi^iTP=kL91xPLjR1*JWE)@*VxG{jYGkm z!*UEPAFaElS?Gm9b6Uh^koqe;O9OsdddeJVv9+}u$=g~U%eW^wR<~#h6DL{9-dwlq zWrD+I6NwkAVBWrJ4$}xqg@Q&aY>SjD*$f7xwIwA=6Evl!5Cl*GMp#U383;fLeU_L~6< zbsBvkjJZ>Qx*bnoHA_e|b*@4@>fCu_Rx za+<-DWJg)is=++TBnDsu&C%K&EvU_t@LbMmoHH>av!X5Pt)?L{9z~&`g|aMqU9Fp? zGL;)$-XvEArFy=jSV3q#GBUEcqg`MRj*oAoc~-0(qm4g4z6H}7WulYjQ2_TvY-8yI z24~h6G+;KnN`hIBvIk*9UaSlh4YBVxx3-vEQ+`J|qvbH-jh>1FlKaJFizcbY5aFy0 zRec*>3uTAA81teoG&g2~KHA&Du`w`5&X%a{!a9qV<8XgTD%l2%jLI?VFj1nkdZ-Ne zI9WebAkHm!bQJd=+KgM~7J(NMqb1K@ao~Ma5%zm;T~OA58UkjmcUZBJ``?WDOUfeE z&C0Pw7)2X)gV`ricAQ7y`onyK^q%1nm%M4$&A5zlIArn~^wI7?U7>zN2`v;-4H%bx z&*m zYnZ8?8~ug+H=1yHkZYSXi0Y}i%fvmgk@!urf7nvwJZ>4+Sh|JNKE^6wDNk{_CyVkn zrejE>Fen;>ybx@^Y+~vcCxh&j)6E+m0GrE;s9ej(_J;K+*WH^uY*7zNuBweiPt?%| zW^FndrL>8g(~3E%G|d5p9OR%k()WXsJA&%2TkJm5E$D4R8XKn+?5Cuy2P*tCxF8C) z$>);p$-_*kQ3S_fhB^(q$ljdEs*0P^px(tM*rgh-e3zQl_>oYM1Kz|DXi%nc96JxF zo%}S85mO)t9eYPd+$%$GDdO<-w3Xr9a2Vw3sH(`x(p0way0hB+10|$l|4ypkh;C7H zeTG$S`%2-?*YmuNzG{I&iKP%qwz}`BPUJ91IJ(T@(xKliF9@)nqM?7}vZFfDoxWT> zsFSK8PudE*c74n~YLAsP?$^@$*;;9Ju%t~*pROka4vhUdsvcBo*DcjT{UICJ-i%7^ zdU4#+Iznq&Iv72=Z;`X4kq7z;ga>g;>8!P)R`lNaZmno$#VA9xs`(Y#17clv_r`#aP0ME3S%dEiW5l8__;jHxMQmVqL6B5_4@TI>0U+* z6b)MCu6csvvw(BpRPDNKPQ5SBQWfPy;Zg<*g?Wgi{k&UAvXOm z;#i9Ri|6yNBDQ}C_&)G7Ab|G)?*{&fSpFjLd0-QG0+#@FHUQ4+8fCe@D#z96+%= z11@16Uj}GCAEG%`pNfHsfr^2Ofr^2Ofr^3uIR@f1$PrZVb@iW+IK0u>9#P2lh%U<$ zRQKZgIszT!m0b5!j%2bv(&0E7$H&~Q!E!j$vt|5g^ z*)e2LaiGM>axjk4`5q%^n=V%`htx5->Fbc9wb61)Vwgj-LfZCfXGPkmH1JN;P$iO8 zNKdImCoWgL5Fum4hqyu3a(12jB}KFzv_e;_31n=Wj*{{p3b~dQ(#a}HpdqRofGnH}@6ZOqf^@ORWu1!QIN&gXwn9pUot$NC!3a3~(u_YiwjY8=&73>P+ z0wPBzjB5>6^I@7uh6_=vI}~M>9v#)_(NV2Y(~nIO1}0CchEr%qF^Ij1LP?iL~L(~s39_gx{6ItPun&Yp~x1YR~_u* z878%33?VG{;wBz=*?5d)H~LOyvuL8!blrvdnfaqkbR*=tAsi_}mCV8=5`F!)Y9dN_ zhkK|3t7Z%g6gWr7%uubT0&UpXG^pE%QZFFAdUI8iFcp}EdW=zLOAxYR3{_8nBH&)L zfuZ#H$dh@&BA!7WoP5u$bBOY_r7@^CrSPHUQ1c_sfpXKe4$|a~nbQ73pAtvC*_w+B y7Y3A3^VS-dC@0;>qwL5#>DH54JjKx>`cp5Kxp>CcuUDx7@JsnEt6y9ss{ajb{|2Z4 literal 0 HcmV?d00001 diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index c34b53ee..aa90e249 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -162,7 +162,7 @@ env.prototype.init = function(opts){ } else { var etcd_redrouter = { - docker: containerId, + docker_container: containerId, port: 22, username: "root", allowed_auth: ["password"] @@ -172,10 +172,10 @@ env.prototype.init = function(opts){ var dir = slf.root_dom.split('.'); dir.reverse().push(slf.usr,'A'); slf.helixKey = dir.join('/'); - slf.redRouterKey = '/redrouter/ssh::'+slf.usr; + slf.redRouterKey = '/redrouter/SSH::'+slf.usr; //set etcd record for redrouter - etcd.set(slf.redRouterKey,etcd_redrouter,function(err,res){ + etcd.set(slf.redRouterKey,JSON.stringify(etcd_redrouter),function(err,res){ if(err){ TuxLog.log('debug', 'error creating redrotuer etcd record: '+err); reject("Internal error"); diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 1721df98..f180e405 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -14,9 +14,10 @@ Meteor.methods({ */ 'prepareLab': function(user : string, labId : string){ TuxLog.log("warn","here"); + var uId = Meteor.user().profile.nickname; var sessionAsync = Meteor.wrapAsync(prepLab); try{ - var res = sessionAsync(user,labId); + var res = sessionAsync(uId,labId); return res; } catch(e){ From 3763331eed5ca4956daf4c529dcfbd5e35021c51 Mon Sep 17 00:00:00 2001 From: vagrant Date: Wed, 20 Jul 2016 22:54:10 +0000 Subject: [PATCH 41/49] deleted debug line --- client/imports/ui/components/explore/explore.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/client/imports/ui/components/explore/explore.ts b/client/imports/ui/components/explore/explore.ts index 0c982380..2c7e16ed 100644 --- a/client/imports/ui/components/explore/explore.ts +++ b/client/imports/ui/components/explore/explore.ts @@ -51,7 +51,6 @@ export class ExploreView extends MeteorComponent { mdIconRegistry.setDefaultFontSetClass('tuxicon'); this.subscribe('explore-courses', () => { - console.log("here"); this.courses = courses.find().fetch(); }, true); } From 9cbe003363e66c18a95415f55a6be8962c129e92 Mon Sep 17 00:00:00 2001 From: vagrant Date: Wed, 20 Jul 2016 22:58:42 +0000 Subject: [PATCH 42/49] fixed minor excess code --- client/imports/ui/pages/lab/taskview.ts | 4 ---- server/imports/api/.lab.env.js.swp | Bin 16384 -> 0 bytes 2 files changed, 4 deletions(-) delete mode 100644 server/imports/api/.lab.env.js.swp diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index 60770ef5..41bfe547 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -24,7 +24,6 @@ // Meteor method imports import "../../../lab/methods.ts" - import { labs } from '../../../../../collections/labs.ts'; // Define TaskView Component @Component({ @@ -44,8 +43,6 @@ @InjectUser('user') export default class TaskView extends MeteorComponent { user: Meteor.User; - userid: number; - cur_user: boolean; public auth : any; @ViewChild(Terminal) term : Terminal; @@ -54,7 +51,6 @@ export default class TaskView extends MeteorComponent { constructor() { super(); - var slf = this; } ngAfterViewInit(){ diff --git a/server/imports/api/.lab.env.js.swp b/server/imports/api/.lab.env.js.swp deleted file mode 100644 index 5dd8531624faa4c86668c4c255f37079b4cf5d6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeHOTWlOx8J;Gg)V%_&xV)WgC1%!M@5D~pq;Xxf#D-XH<0!GyhZZg4nd9Aw=dzh| z#+Nu&0riEO5aKF|5SQ|R3ROYygwhA3BCg`0fSLy+PzB-vH4oe#pef&f&Y9iWwOxfo zNFdEhpLh0L{_~&j{O6zZ|1(}XaAxjNcDQ-S!sjiP_0*M5KE{vSWbLh6)~eUeyhKvX z8-AkH_o7ZJWK&%QY3zl`4n5peFLPzS9(hZy;MpqA+%WE@nG~+q4P6vBd9vC(D|YBx z6;%vW3|ub*w^;`#Ck~L5yKDQ|oo`#bUV&Brih+uOih+uOih+uOih+uOih+uO|04!u zcc1kn^xb20{+Ri`Vd(pH^J$y%j}O&fG4Z@X)VxVH6 zVxVH6VxVH6VxVH6VxVH6VxVH6V&K2PfEQTS?T~wh5&(GqU&Q}^zQeM91bhql1P}oy zfJcD`fOi6S0awuZHQ*KC1>g(7XMj%uTfidF1nR)0+brvwz%zgZjsv5B1K7YFz~64Q zte1g{z}JDN01x;8umCiGcLDDJ-VVHai)H;Bcpi8T_%`q*pbg9ehk=8@jlf@TwyfU+ zzXZMubbv)*4tNN-2l&T`WnBjT1pEfL2&@4sKnr*bco=vqFaqoa{&OEv;iM@0GI}D0e*X3U=BDAOal9W%WndQz{|i_ zfzJYGfd_&6fhk}=a69m?eU|k*;K#uCfMMXUn3$jAi^R_oY*tOC-+{FJiMu}jYC-e@pG>Lg4S;rG>iSwi^iTP=kL91xPLjR1*JWE)@*VxG{jYGkm z!*UEPAFaElS?Gm9b6Uh^koqe;O9OsdddeJVv9+}u$=g~U%eW^wR<~#h6DL{9-dwlq zWrD+I6NwkAVBWrJ4$}xqg@Q&aY>SjD*$f7xwIwA=6Evl!5Cl*GMp#U383;fLeU_L~6< zbsBvkjJZ>Qx*bnoHA_e|b*@4@>fCu_Rx za+<-DWJg)is=++TBnDsu&C%K&EvU_t@LbMmoHH>av!X5Pt)?L{9z~&`g|aMqU9Fp? zGL;)$-XvEArFy=jSV3q#GBUEcqg`MRj*oAoc~-0(qm4g4z6H}7WulYjQ2_TvY-8yI z24~h6G+;KnN`hIBvIk*9UaSlh4YBVxx3-vEQ+`J|qvbH-jh>1FlKaJFizcbY5aFy0 zRec*>3uTAA81teoG&g2~KHA&Du`w`5&X%a{!a9qV<8XgTD%l2%jLI?VFj1nkdZ-Ne zI9WebAkHm!bQJd=+KgM~7J(NMqb1K@ao~Ma5%zm;T~OA58UkjmcUZBJ``?WDOUfeE z&C0Pw7)2X)gV`ricAQ7y`onyK^q%1nm%M4$&A5zlIArn~^wI7?U7>zN2`v;-4H%bx z&*m zYnZ8?8~ug+H=1yHkZYSXi0Y}i%fvmgk@!urf7nvwJZ>4+Sh|JNKE^6wDNk{_CyVkn zrejE>Fen;>ybx@^Y+~vcCxh&j)6E+m0GrE;s9ej(_J;K+*WH^uY*7zNuBweiPt?%| zW^FndrL>8g(~3E%G|d5p9OR%k()WXsJA&%2TkJm5E$D4R8XKn+?5Cuy2P*tCxF8C) z$>);p$-_*kQ3S_fhB^(q$ljdEs*0P^px(tM*rgh-e3zQl_>oYM1Kz|DXi%nc96JxF zo%}S85mO)t9eYPd+$%$GDdO<-w3Xr9a2Vw3sH(`x(p0way0hB+10|$l|4ypkh;C7H zeTG$S`%2-?*YmuNzG{I&iKP%qwz}`BPUJ91IJ(T@(xKliF9@)nqM?7}vZFfDoxWT> zsFSK8PudE*c74n~YLAsP?$^@$*;;9Ju%t~*pROka4vhUdsvcBo*DcjT{UICJ-i%7^ zdU4#+Iznq&Iv72=Z;`X4kq7z;ga>g;>8!P)R`lNaZmno$#VA9xs`(Y#17clv_r`#aP0ME3S%dEiW5l8__;jHxMQmVqL6B5_4@TI>0U+* z6b)MCu6csvvw(BpRPDNKPQ5SBQWfPy;Zg<*g?Wgi{k&UAvXOm z;#i9Ri|6yNBDQ}C_&)G7Ab|G)?*{&fSpFjLd0-QG0+#@FHUQ4+8fCe@D#z96+%= z11@16Uj}GCAEG%`pNfHsfr^2Ofr^2Ofr^3uIR@f1$PrZVb@iW+IK0u>9#P2lh%U<$ zRQKZgIszT!m0b5!j%2bv(&0E7$H&~Q!E!j$vt|5g^ z*)e2LaiGM>axjk4`5q%^n=V%`htx5->Fbc9wb61)Vwgj-LfZCfXGPkmH1JN;P$iO8 zNKdImCoWgL5Fum4hqyu3a(12jB}KFzv_e;_31n=Wj*{{p3b~dQ(#a}HpdqRofGnH}@6ZOqf^@ORWu1!QIN&gXwn9pUot$NC!3a3~(u_YiwjY8=&73>P+ z0wPBzjB5>6^I@7uh6_=vI}~M>9v#)_(NV2Y(~nIO1}0CchEr%qF^Ij1LP?iL~L(~s39_gx{6ItPun&Yp~x1YR~_u* z878%33?VG{;wBz=*?5d)H~LOyvuL8!blrvdnfaqkbR*=tAsi_}mCV8=5`F!)Y9dN_ zhkK|3t7Z%g6gWr7%uubT0&UpXG^pE%QZFFAdUI8iFcp}EdW=zLOAxYR3{_8nBH&)L zfuZ#H$dh@&BA!7WoP5u$bBOY_r7@^CrSPHUQ1c_sfpXKe4$|a~nbQ73pAtvC*_w+B y7Y3A3^VS-dC@0;>qwL5#>DH54JjKx>`cp5Kxp>CcuUDx7@JsnEt6y9ss{ajb{|2Z4 From a4866a05c4e8e0e63f4b771fcf87c7c6a3f51e67 Mon Sep 17 00:00:00 2001 From: vagrant Date: Wed, 20 Jul 2016 23:03:03 +0000 Subject: [PATCH 43/49] minor indentation fix --- server/imports/api/lab.env.js | 84 +++++++++++++++++------------------ 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index aa90e249..4a0912dc 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -162,48 +162,44 @@ env.prototype.init = function(opts){ } else { var etcd_redrouter = { - docker_container: containerId, - port: 22, - username: "root", - allowed_auth: ["password"] - } - - //etcd directory for helix record - var dir = slf.root_dom.split('.'); - dir.reverse().push(slf.usr,'A'); - slf.helixKey = dir.join('/'); - slf.redRouterKey = '/redrouter/SSH::'+slf.usr; - - //set etcd record for redrouter - etcd.set(slf.redRouterKey,JSON.stringify(etcd_redrouter),function(err,res){ - if(err){ - TuxLog.log('debug', 'error creating redrotuer etcd record: '+err); - reject("Internal error"); - } - else{ - //set etcd record for helixdns - slf.docker.getContainer(containerId).inspect(function(err,container){ - if(err){ - TuxLog.log('warn', 'docker cannot find the container it just created: '+err); - reject("Internal error"); - //TODO: get the actual information that we actually want. Perhaps change this entirely - } - else{ - - //set etcd record for helix - etcd.set(slf.helixKey,container.NetworkSettings,function(err,res){ - if(err){ - TuxLog.log('warn','error creating helix etcd record: '+err); - reject("Internal error"); - } - else{ - slf.vmList.labVm = slf.labVm; - resolve(); - } - }); - } - }); - } + docker_container: containerId, + port: 22, + username: "root", + allowed_auth: ["password"] + } + //etcd directory for helix record + var dir = slf.root_dom.split('.'); + dir.reverse().push(slf.usr,'A'); + slf.helixKey = dir.join('/'); + slf.redRouterKey = '/redrouter/SSH::'+slf.usr; + + //set etcd record for redrouter + etcd.set(slf.redRouterKey,JSON.stringify(etcd_redrouter),function(err,res){ + if(err){ + TuxLog.log('debug', 'error creating redrotuer etcd record: '+err); + reject("Internal error"); + } + else{ + //set etcd record for helixdns + slf.docker.getContainer(containerId).inspect(function(err,container){ + if(err){ + TuxLog.log('warn', 'docker cannot find the container it just created: '+err); + reject("Internal error"); + //TODO: get the actual information that we actually want. Perhaps change this entirely + } + else{ + //set etcd record for helix + etcd.set(slf.helixKey,container.NetworkSettings,function(err,res){ + if(err){ + TuxLog.log('warn','error creating helix etcd record: '+err); + reject("Internal error"); + } + else{ + slf.vmList.labVm = slf.labVm; + resolve(); + } + }); + } }); } }); @@ -211,7 +207,9 @@ env.prototype.init = function(opts){ }); } }); - }); + } +}); +}); } /* creates a new container with an image from the options provided, From c96e7a4cf9fd02afdb8ab66f24e2ce6a62f3359c Mon Sep 17 00:00:00 2001 From: vagrant Date: Thu, 21 Jul 2016 21:08:24 +0000 Subject: [PATCH 44/49] reference fixes --- client/imports/ui/pages/lab/taskview.ts | 5 +++- server/imports/api/lab.env.js | 6 +--- server/imports/api/lab.session.js | 35 +++++++++++++++-------- server/imports/lab/methods.ts | 38 ------------------------- 4 files changed, 28 insertions(+), 56 deletions(-) diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index 94884168..acf6a653 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -58,7 +58,10 @@ export default class TaskView extends MeteorComponent { ngAfterViewInit(){ var slf = this; Meteor.call('prepareLab',"1","1", function(err,res){ - slf.labMarkdown = "# Sander \n ## are you sure this will work?"; + + //slf.labMarkdown = "# Sander \n ## are you sure this will work?"; + slf.labMarkdown = res.taskList[0].md; + console.log(slf.labMarkdown); slf.auth = { username: Meteor.user().profile.nickname, diff --git a/server/imports/api/lab.env.js b/server/imports/api/lab.env.js index 4a0912dc..4465729e 100644 --- a/server/imports/api/lab.env.js +++ b/server/imports/api/lab.env.js @@ -41,9 +41,7 @@ env.prototype.setUser = function(user){ } //returns resolved promise for chaining -env.prototype.start = function(){ - return Promise.resolve(); -} +env.prototype.start = () => {return Promise.resolve()} /* deleteRecords * delete helix and redRouter records for given user @@ -341,7 +339,6 @@ env.prototype.updateVm = function(vmName, opts) { env.prototype.shell = function(vmName,command,opts) { var slf = this; return function(){ - console.log("in env.shell"); return new Promise(function(resolve,reject){ if(!_.has(slf.vmList,vmName)){ TuxLog.log('labfile_error','trying to run shell on non-existing vm'); @@ -391,7 +388,6 @@ env.prototype.shell = function(vmName,command,opts) { * calls callback(password) */ env.prototype.getPass = function(callback){ - console.log("hereeee"); TuxLog.log("warn","here in getPass"); this.shell("labVm", "cat /pass")() .then(function(sOut){ callback(null,sOut); }, function(s1,s2,s3){ diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index 9009db54..43949b45 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -98,27 +98,38 @@ session.prototype.start = function(callback){ this.lab.taskNo = 1; this.lab.setup(this.env) .then(function(){ - // slf.lab.tasks(this.env); + return new Promise(function(resolve,reject){ + try{ + slf.lab.tasks(this.env); + console.log("resolving"); + resolve(); + } + catch(e){ + reject(e); + } + }); callback(null); }, function(err){ TuxLog.log("warn","error during labfile_setup: "+err); callback("Internal Service Error") } - ) - + ) .then(function(){ - if(!this.lab.currentTask.next){ + console.log("resolved"); + if(!slf.lab.currentTask.next){ + console.log("uh oh"); TuxLog.log('warn','labfile tasks not properly chained at start'); callback("Internal Service error"); } + else{ - this.lab.currentTask = this.lab.currentTask.next; - console.log("no"+slf.lab.taskNo); - this.lab.currentTask.sFn().then(function(){console.log("no"+slf.lab.taskNo)}).then(function(){ - console.log("no"+slf.lab.taskNo); - console.log("start"); - callback(null); }); + console.log("so far so good"); + slf.lab.currentTask = slf.lab.currentTask.next; + console.log(slf.lab.currentTask.setupFn.toString()); + + slf.lab.currentTask.setupFn(slf.env) + .then(callback(null)); } }, function(){ @@ -137,9 +148,9 @@ session.prototype.next = function(callback){ TuxLog.log("debug","trying to call nextTask on last task"); callback("Internal error",null); } - this.lab.currentTask.vFn().then(function(){ + this.lab.currentTask.verifyFn(slf.env).then(function(){ slf.lab.currentTask = slf.lab.currentTask.next; - slf.lab.currentTask.sFn() + slf.lab.currentTask.setupFn() .then(function(){ slf.lab.taskNo += 1; callback(null,slf.parseTasks());}) diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index f180e405..203adcb8 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -24,44 +24,6 @@ Meteor.methods({ TuxLog.log("warn",e); throw new Meteor.Error(e); } - /* - var session = new LabSession(); - var uId = Meteor.user().profile.nickname; - - //set asynchronous methods - var sessionAsync = Meteor.wrapAsync(session.init,session); - - try{ - //run session.init get ssh info - var sessionRes = sessionAsync(uId,labId); - var sshInfo = {host: nconf.get("domain_root"), pass: sessionRes.sshPass} - - var optsp = {'fields': { - 'labfile' : 0, - 'lab_name': 0, - 'course_id': 0, - 'updated': 0, - 'disabled': 0, - 'hidden': 0 - }}; - console.log(session.lab.taskNo); - var tasks = Collections.labs.findOne({_id: labId}).tasks; - var finalTasks = tasks.map(function(task){ - if(task._id <= sessionRes.taskNo){ - return {title: task.name, md: task.md}; - } - else{ - return {title: task.name, md: null}; - } - }); - console.log(sessionRes.taskNo); - var result = {sshInfo: sshInfo, taskList: finalTasks}; - return result; - } - catch(e){ - TuxLog.log("warn",new Meteor.Error(e)); - throw new Meteor.Error(e); - }*/ }, 'nextTask': function(labId : string){ /**session.next(cb) From 0594b7dd8b8e482931fdd2cf2b3fb2075b1429be Mon Sep 17 00:00:00 2001 From: vagrant Date: Thu, 21 Jul 2016 21:50:06 +0000 Subject: [PATCH 45/49] fixes to nextTask --- client/imports/ui/pages/lab/taskview.html | 2 +- client/imports/ui/pages/lab/taskview.ts | 9 ++++++- server/imports/api/lab.session.js | 33 ++++++++++++++++------- server/imports/lab/methods.ts | 9 ++++--- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/client/imports/ui/pages/lab/taskview.html b/client/imports/ui/pages/lab/taskview.html index 5f306ab4..acc19812 100644 --- a/client/imports/ui/pages/lab/taskview.html +++ b/client/imports/ui/pages/lab/taskview.html @@ -8,7 +8,7 @@

Checking Task...

- diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index acf6a653..ee0318d7 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -57,7 +57,7 @@ export default class TaskView extends MeteorComponent { ngAfterViewInit(){ var slf = this; - Meteor.call('prepareLab',"1","1", function(err,res){ + Meteor.call('prepareLab',"1", function(err,res){ //slf.labMarkdown = "# Sander \n ## are you sure this will work?"; slf.labMarkdown = res.taskList[0].md; @@ -72,4 +72,11 @@ export default class TaskView extends MeteorComponent { console.log("fired",err,res); }); } + nextTask(){ + console.log("proceeding"); + + Meteor.call('nextTask',"1",function(err,res){ + console.log("yay"); + }); + } } diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index 43949b45..91dd6c74 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -144,20 +144,33 @@ session.prototype.start = function(callback){ */ session.prototype.next = function(callback){ var slf = this; + + //check if currentTask is the last task if(this.lab.currentTask.isLast()){ TuxLog.log("debug","trying to call nextTask on last task"); callback("Internal error",null); } - this.lab.currentTask.verifyFn(slf.env).then(function(){ - slf.lab.currentTask = slf.lab.currentTask.next; - slf.lab.currentTask.setupFn() - .then(function(){ - slf.lab.taskNo += 1; - callback(null,slf.parseTasks());}) - }, - function(err){ - callback(err,null); - }); + + //if it is not the last task... + else{ + console.log("in session.next, success case"); + console.log(slf.lab.currentTask.verifyFn.toString()); + slf.lab.currentTask.verifyFn(slf.env) + .then(function(){ + slf.lab.currentTask = slf.lab.currentTask.next; + slf.lab.currentTask.setupFn(slf.env) + .then(function(){ + slf.lab.taskNo += 1; + callback(null,null); + }, + function(err){ + callback(err,null); + }); + }, + function(err){ + callback(err,null); + }); + } } /* end: verifies that last task is completed diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 203adcb8..8d1591f5 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -12,7 +12,7 @@ Meteor.methods({ * callback: (err,pass) * implement loading wheel, md fetch, course record create in callback */ - 'prepareLab': function(user : string, labId : string){ + 'prepareLab': function(labId : string){ TuxLog.log("warn","here"); var uId = Meteor.user().profile.nickname; var sessionAsync = Meteor.wrapAsync(prepLab); @@ -32,7 +32,8 @@ Meteor.methods({ * change task markdown -frontend * change course records if passed */ - var uId = Meteor.userId(); + + var uId = Meteor.user().profile.nickname; SessionCache.get(uId,labId,function(err,res){ if(err){ TuxLog.log("warn",err); @@ -43,7 +44,9 @@ Meteor.methods({ throw new Meteor.Error("Internal Service Error"); } else{ - var nextAsync = Meteor.wrapAsync(res.next,res); + console.log("got session"); + var nextAsync = Meteor.wrapAsync(res.next,res); + console.log("wrapped next"); try{ var result = nextAsync(); return "success"; //TODO: @Derek what to return here? From ecf54d1697c816272a6ec811da5476e890581c34 Mon Sep 17 00:00:00 2001 From: vagrant Date: Thu, 21 Jul 2016 22:02:07 +0000 Subject: [PATCH 46/49] merged with master --- public/assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/assets b/public/assets index bac57f8b..18b772f4 160000 --- a/public/assets +++ b/public/assets @@ -1 +1 @@ -Subproject commit bac57f8b0ed7c81e45d1dcad51ecb193bfc2885e +Subproject commit 18b772f43ccd9e1a267c92abeed12b593bb54f49 From 73aaefa2a5b60b2469fd8e5b6df9ae7d7613cde7 Mon Sep 17 00:00:00 2001 From: vagrant Date: Thu, 21 Jul 2016 22:04:10 +0000 Subject: [PATCH 47/49] minor changes --- client/imports/ui/pages/lab/taskview.ts | 1 - server/imports/lab/methods.ts | 2 -- 2 files changed, 3 deletions(-) diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index ba27dc67..7602e9a3 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -15,7 +15,6 @@ import { MATERIAL_PROVIDERS, MATERIAL_DIRECTIVES } from 'ng2-material'; import { MD_INPUT_DIRECTIVES } from '@angular2-material/input'; - import { MD_INPUT_DIRECTIVES } from '@angular2-material/input'; import { MD_SIDENAV_DIRECTIVES } from '@angular2-material/sidenav'; import { MD_TOOLBAR_DIRECTIVES } from '@angular2-material/toolbar'; import { InjectUser } from 'angular2-meteor-accounts-ui'; diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 8d1591f5..998480b8 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -44,9 +44,7 @@ Meteor.methods({ throw new Meteor.Error("Internal Service Error"); } else{ - console.log("got session"); var nextAsync = Meteor.wrapAsync(res.next,res); - console.log("wrapped next"); try{ var result = nextAsync(); return "success"; //TODO: @Derek what to return here? From de776e0f6bc9b313f8734c2dc7a11109a06c49ff Mon Sep 17 00:00:00 2001 From: vagrant Date: Thu, 21 Jul 2016 22:21:04 +0000 Subject: [PATCH 48/49] fixed merge problems --- client/imports/ui/pages/lab/taskview.ts | 2 +- server/imports/lab/labMethods.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index 7602e9a3..9969489c 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -75,7 +75,7 @@ export default class TaskView extends MeteorComponent { ngAfterViewInit(){ var slf = this; Meteor.call('prepareLab',"1", function(err,res){ - + console.log('here'); //slf.labMarkdown = "# Sander \n ## are you sure this will work?"; slf.tasks = res.taskList; diff --git a/server/imports/lab/labMethods.ts b/server/imports/lab/labMethods.ts index fc824bf3..d59de049 100644 --- a/server/imports/lab/labMethods.ts +++ b/server/imports/lab/labMethods.ts @@ -62,13 +62,13 @@ export function prepLab(user : string, labId : string, callback : any) : any{ var tasks = Collections.labs.findOne({_id: labId}).tasks; var finalTasks = tasks.map(function(task){ if(task._id < res.taskNo){ - return {id:task._id,name: task.name, md: task.md, completed: true}; + return {id: task._id, name: task.name, md: task.md, completed: true}; } else if(task._id == res.taskNo){ - return{id:task_id,name: task.name, md: task.md, completed: false + return{id: task._id, name: task.name, md: task.md, completed: false}; } else{ - return {id: task._id,name: task.name, md: null,completed:false}; + return {id: task._id, name: task.name, md: null, completed:false}; } }); callback(null,{sshInfo: sshInfo, taskList: finalTasks}); From 508d1a6618e7abba51e20a6c342318414d0ce912 Mon Sep 17 00:00:00 2001 From: vagrant Date: Fri, 22 Jul 2016 16:29:56 +0000 Subject: [PATCH 49/49] fixed md view and swithces --- client/imports/ui/pages/lab/taskview.ts | 19 ++++++-- public/assets | 2 +- server/imports/api/lab.session.js | 3 +- server/imports/lab/.labMethods.ts.swp | Bin 0 -> 12288 bytes server/imports/lab/labMethods.ts | 62 ++++++++++++++++++++---- server/imports/lab/methods.ts | 39 ++++++--------- 6 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 server/imports/lab/.labMethods.ts.swp diff --git a/client/imports/ui/pages/lab/taskview.ts b/client/imports/ui/pages/lab/taskview.ts index 9969489c..72dce03f 100644 --- a/client/imports/ui/pages/lab/taskview.ts +++ b/client/imports/ui/pages/lab/taskview.ts @@ -78,22 +78,31 @@ export default class TaskView extends MeteorComponent { console.log('here'); //slf.labMarkdown = "# Sander \n ## are you sure this will work?"; slf.tasks = res.taskList; - + slf.toTask(slf.tasks[0]); slf.auth = { username: Meteor.user().profile.nickname, password: res.sshInfo.pass, domain: "10.100.1.11" }; + console.log("here"); slf.term.openTerminal(slf.auth); console.log("fired",err,res); }); } nextTask(){ console.log("proceeding"); - - Meteor.call('nextTask',"1",function(err,res){ - console.log("yay"); - }); + var slf = this; + Meteor.call('nextTask',"1",function(err,res){ + if(err){ + console.log("try again"); + } + else{ + console.log(res); + slf.tasks = res.taskList + slf.toTask(slf.tasks[res.taskNo-1]); + } + console.log("yay"); + }); } toTask(task) { this.labMarkdown = task.md; diff --git a/public/assets b/public/assets index 18b772f4..bac57f8b 160000 --- a/public/assets +++ b/public/assets @@ -1 +1 @@ -Subproject commit 18b772f43ccd9e1a267c92abeed12b593bb54f49 +Subproject commit bac57f8b0ed7c81e45d1dcad51ecb193bfc2885e diff --git a/server/imports/api/lab.session.js b/server/imports/api/lab.session.js index 8a0f50ba..605fe8a4 100644 --- a/server/imports/api/lab.session.js +++ b/server/imports/api/lab.session.js @@ -160,7 +160,8 @@ session.prototype.next = function(callback){ slf.lab.currentTask.setupFn(slf.env) .then(function(){ slf.lab.taskNo += 1; - callback(null,null); + console.log("all is well",slf.lab.taskNo); + callback(null,slf.lab.taskNo); }, function(err){ callback(err,null); diff --git a/server/imports/lab/.labMethods.ts.swp b/server/imports/lab/.labMethods.ts.swp new file mode 100644 index 0000000000000000000000000000000000000000..bddd4cb0181e53647933249e2ebbfbc32e7b4200 GIT binary patch literal 12288 zcmeI2&x;&I6vr$6h^uBdK@p5OSQ!a3V}_nY1!3X}AqHLYQ#K|iY4% z@73#C(u+He&K=+{IxjH%HZivQwe!bzH>TM9lZ-99OR*a!)N;#T5VhT)8_C4U?!2hy z`r(8g&1E-kCh1DxE;glzmqpz4d;KU*WRt4E0g-egPdbU5(A`#91*`&hq`)+L{<)ny zXozPjTlwRUy>UmQ+0Ir0tAJI&Dqt0`3RnfK0#*U5z`dnF(qG5k#ggyS%Ra5I>q=K$ zv=^&@Rlq7>6|f3e1*`&A0jq#jz$#!BunJfO?m-1ykFgp2u|IP^7LWh`H-G;u!__YI7F3%&*yz&UUh z48TdS7iItKeBs13ynO_6_(Lyax_}888L@d5E!_;5xVhE`sym3~<3dup8W158J?HZ~>eH ztKcYj3Ty)F0Rw+Mh;@M*;1XB?FN2-n<^zoV27Uq8z<1yy@IE*Vj(|O28`uJ-!8Q2r zD)<6?3O)e)z$|EjZD0#{0&D{0?`dFvMFmzF=c{%6gG=@=6?f^oye?}m)Mw@4Q&i#{ zpTq=+nOoN~?NL+bhzb}&(kA;*CPUVA93k5x&>czPTq!=($qN`bnsT+( zLB`cmc!nzn@v>kr7Y2zH`dVt($TMxxjkmZ=Vn1AJWZm=PFbYxShNtVeEJwZvX-IGr z+D3d+F3LvtL+Ml~OWB?it$bxFu_dF3+TYLwjviem$U%HEd@Tk7QOf?=)`<|OjsBcGUEX9I9-UEJK2;H6- z8ww2_KM+;eF`R?UjQWY}labYqF9J`ZquwC7_$Cf=e~VKbpX7-scCuYitIUOoh(kBv z^Z0(xZwsz=M}5>c6Lu5=Tn9YuqtTsPaAf{iEyX8-Ywm~4g%hUf$D+UAU8LYDZx-E@ zjSF@3hEW@?P&US+O79q42HAcwO)8~#eCUv6)hv=t*c%aJk)(0R2fo+JlDz{rHaPiA zm+7{_duYzK6?RImA3$uc)p3!^bU=-JM-6;C<5C84dYCmInwQ6>jF~-$qY$UDVp+3@z$|y8Y))!;!iGo06 zZ#n5;V@L-xc!xq!8<4dv<@?oomM7#cW|D3xmE^%e;~tDq4%6NuMW=}fN~{PI+ES!h zITi}9cq1w8e$%^fL{LWpTC7Q4I@8ce0WSeFvPvFB6;%7(PO6maM7T`Zkn&yb3(CiO zN^{VdupRLP_d`GN-M~L1Jd^XsgSu$f+7gY~m`kk$;k?-#Rdqra&c{~@a|+UNq_^zQ zpXqJRlU7yHQ)L>C=1dy8kT zf-vO=i;gt=-5i0jZd1ieFQPmL+{Oz-AF({q4%}E|3KuewN)@|Uu{k?(OlnZNPiiR| kX4=V@x%c4CSe#7#Sk$VH({%ejePZuOeV%?tR^i@%0o5EgCIA2c literal 0 HcmV?d00001 diff --git a/server/imports/lab/labMethods.ts b/server/imports/lab/labMethods.ts index d59de049..3c651edf 100644 --- a/server/imports/lab/labMethods.ts +++ b/server/imports/lab/labMethods.ts @@ -41,6 +41,23 @@ function getSession(user : string, labId : string, callback : any) : void{ } }); } + +function mapTasks(labId : string,taskNo : number, callback) : any { + var tasks = Collections.labs.findOne({_id : labId}).tasks; + console.log("mapping"); + var finalTasks = tasks.map(function(task){ + if(task._id < taskNo){ + return {id: task._id, name: task.name, md: task.md, completed: true}; + } + else if(task._id == taskNo){ + return{id: task._id, name: task.name, md: task.md, completed: false}; + } + else{ + return {id: task._id, name: task.name, md: null, completed:false}; + } + }); + callback(null,finalTasks); +} export function prepLab(user : string, labId : string, callback : any) : any{ TuxLog.log("warn","prepLab"); getSession(user, labId, function(err,res){ @@ -59,19 +76,46 @@ export function prepLab(user : string, labId : string, callback : any) : any{ 'hidden': 0 }}; var sshInfo = {host : nconf.get("domain_root"), pass: res.sshPass}; - var tasks = Collections.labs.findOne({_id: labId}).tasks; - var finalTasks = tasks.map(function(task){ - if(task._id < res.taskNo){ - return {id: task._id, name: task.name, md: task.md, completed: true}; - } - else if(task._id == res.taskNo){ - return{id: task._id, name: task.name, md: task.md, completed: false}; + mapTasks(labId,res.taskNo,function(err,res){ + if(err){ + callback(err,null); } else{ - return {id: task._id, name: task.name, md: null, completed:false}; + console.log("calling back"); + callback(null,{sshInfo: sshInfo, taskList: res}); } }); - callback(null,{sshInfo: sshInfo, taskList: finalTasks}); } }); } + +export function next(uId : string,labId : string, callback : any) : void{ + SessionCache.get(uId, labId, function(err,result){ + console.log("result.lab.taskNo: "+result.lab.taskNo); + if(err){ + TuxLog.log("warn","Session.get Error" + err); + callback(err,null); + } + + else if(!result){ + TuxLog.log("warn","Session.get had no results: "+err); + } + else{ + result.next(function(err,res){ + if(err){ + callback(err,null); + } + else{ + mapTasks(labId,res,function(err,ress){ + if(err){ + callback(err,null); + } + else{ + callback(null,{taskList: ress, taskNo:res}) + } + }); + } + }); + } + }) +} diff --git a/server/imports/lab/methods.ts b/server/imports/lab/methods.ts index 998480b8..d3bcf04a 100644 --- a/server/imports/lab/methods.ts +++ b/server/imports/lab/methods.ts @@ -1,11 +1,16 @@ + +//variable declarations declare var Collections : any; -var LabSession = require('../api/lab.session.js'); declare var TuxLog : any; declare var SessionCache : any; declare var nconf : any; + +//import session constructor var LabSession = require('../api/lab.session.js'); -import{ prepLab } from './labMethods.ts'; +//import sync Meteor methods +import{ prepLab, next } from './labMethods.ts'; + Meteor.methods({ /**prepareLab: prepares a labExec object for the current user * takes the id of the lab and a callback as parameter @@ -34,27 +39,15 @@ Meteor.methods({ */ var uId = Meteor.user().profile.nickname; - SessionCache.get(uId,labId,function(err,res){ - if(err){ - TuxLog.log("warn",err); - throw new Meteor.Error("Internal Service Error"); - } - else if(!res){ - TuxLog.log("warn",new Meteor.Error("SessionCache.get failed to return a session instance")); - throw new Meteor.Error("Internal Service Error"); - } - else{ - var nextAsync = Meteor.wrapAsync(res.next,res); - try{ - var result = nextAsync(); - return "success"; //TODO: @Derek what to return here? - } - catch(e){ - TuxLog.log("warn",e); - throw new Meteor.Error("Internal Service Error"); - } - } - }); + var nextAsync = Meteor.wrapAsync(next); + try{ + var res = nextAsync(uId,labId); + return res; + } + catch(e){ + TuxLog.log(e); + throw new Meteor.Error("Internal Service Error"); + } }, 'endLab': function(labId : string){ /**session.end(cb)