Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 18 commits
  • 9 files changed
  • 0 commit comments
  • 1 contributor
View
45 INSTALL
@@ -1,9 +1,44 @@
-First you'll need these modules on npm (http://npmjs.org):
- npm install dnode png jpeg video base64
+First you'll need node.js. Download, unpack and install it from http://nodejs.org/
-SQLite isn't in npm yet, annoyingly. Anyways, you can get it here:
- http://github.com/grumdrig/node-sqlite.git
+Next, you'll need npm:
-Also add jquery.js, jquery.ui.js, and jquery.mousewheel.js to static/js/vendor/
+ git clone http://github.com/isaacs/npm.git
+ cd npm
+ bash ./scripts/install.sh
+
+Next, you'll need these node.js modules. They can be installed via npm:
+
+ npm install dnode bufferlist rfb png jpeg gif video base64
+
+To get them compiles make sure you have libjpeg, libpng, giflib, libtheora and libogg.
+
+Then get the stackvm itself:
+
+ git clone http://github.com/substack/stackvm.git
+
+Next get jquery, jquery-ui and jquery-mouswheel plugin [1].
+
+Put them in static/js/vendor directory and make sure jquery is named just jquery.js,
+and jquery-ui is named jquery-ui.js.
+
+Then make sure you have qemu and an image you want to run.
+
+Edit data/users.json to add yourself, and then `mkdir -p users/yournick/disks`. Put the
+vm image in that directory.
+
+Then start manager.js:
+
+ node bin/manager.js
+
+And then webstack.js:
+
+ node bin/webstack.js
+
+Now go to http://localhost:9000.
+
+[1]: http://github.com/brandonaaron/jquery-mousewheel
+
+---
TODO: proper package.json, auto-fetch jquery stuff
+
View
12 README
@@ -0,0 +1,12 @@
+
+StackVM is a web-based virtual machine manager where users will
+* interact directly with the graphical or text console
+* drop virtual machines into a virtual network diagram
+* access files on the virtual machine directly
+* create, duplicate, snapshot, and share virtual machine images
+* integrate non-virtual servers into the virtual network
+
+Running: see INSTALL
+
+http://stackvm.com
+
View
2  bin/server.js
@@ -44,7 +44,7 @@ Web(app, users);
Service(users, function (service) {
DNode(service)
.listen(app, {
- ping : 1000,
+ ping : 3600*1000,
timeout : 1000,
transports : 'websocket xhr-multipart xhr-polling htmlfile'
.split(/\s+/),
View
16 data/users.json
@@ -1,3 +1,4 @@
+
{
"ycdemo" : {
"hash" : "",
@@ -6,6 +7,14 @@
"linux-0.2.img" : {
"name" : "simple linux",
"rules" : {}
+ },
+ "dsl-4.4.10.iso" : {
+ "name" : "damn small linux",
+ "rules" : {}
+ },
+ "ReactOS-LiveCD.iso" : {
+ "name" : "reactos",
+ "rules": {}
}
}
},
@@ -28,9 +37,6 @@
"name" : "simple linux",
"rules" : { "moo" : { "spawn" : true } }
},
- "liveandroidv0.3.iso" : {
- "name" : "android"
- },
"ReactOS-LiveCD.iso" : {
"name" : "ReactOS",
"rules" : { "anonymous" : { "spawn" : true } }
@@ -52,6 +58,10 @@
"linux-0.2.img" : {
"name" : "simple linux"
},
+ "linux-0.2.img-vmware" : {
+ "name" : "simple linux @ vmware",
+ "host" : "192.168.1.3:5902"
+ },
"WinXP" : {
"name" : "Windows XP",
"host" : "192.168.1.3:5900"
View
10 lib/models/managers.js
@@ -28,13 +28,13 @@ Store({ filename : __dirname + '/../../data/procs.db', json : true }, function (
});
});
- procs.forEach(function (err, _, proc) {
- console.log('Connecting process ' + proc.pid + ' at ' + proc.address);
- var p = module.exports[proc.engine].connect(proc);
+ procs.forEach(function (proc) {
+ console.log('Connecting process ' + proc.value.pid + ' at ' + proc.value.address);
+ var p = module.exports[proc.value.engine].connect(proc);
if (!p) {
- console.log('Removing proccess ' + proc.pid + ' at ' + proc.address);
+ console.log('Removing proccess ' + proc.value.pid + ' at ' + proc.value.address);
procs.remove(
- proc.address,
+ proc.value.address,
function (err) { if (err) throw err }
);
}
View
78 lib/resources/process.js
@@ -0,0 +1,78 @@
+var EventEmitter = require('events').EventEmitter;
+var FB = require('./fb');
+var Png = require('png').Png;
+var fs = require('fs');
+
+module.exports = Process;
+Process.prototype = new EventEmitter;
+function Process (params) {
+ if (!(this instanceof Process)) return new Process(params);
+ var self = this;
+
+ self.addr = params.proc.addr;
+ self.engine = params.proc.engine;
+ self.disk = params.proc.disk;
+ self.pid = params.proc.pid;
+ self.name = params.name;
+
+ params.proc.on('exit', function () { self.emit('exit', self.addr) });
+
+ self.attach = function (cb) {
+ FB({ addr : self.addr, engine : self.engine }, function (fb) {
+ cb({
+ input : fb.input,
+ encoder : fb.encoder,
+ size : fb.size,
+ });
+ });
+ };
+
+ self.kill = function () {
+ if (self.addr in FB) FB[self.addr].end();
+ self.emit('kill');
+ };
+
+ self.screenshot = function () {
+ FB({ addr : self.addr, engine : self.engine }, function (fb) {
+ fb.encoder.requestRedraw();
+ fb.encoder.once('raw', function g (rect) {
+ fb.encoder.dimensions(function (dims) {
+ var fullScreen = rect.x == 0 && rect.y == 0 &&
+ rect.width == dims.width && rect.height == dims.height;
+ if (!fullScreen) {
+ fb.encoder.once('raw', g);
+ }
+ else {
+ var png = new Png(rect.fb, rect.width, rect.height, 'bgr').
+ encode(function (image) {
+ var fileName = randomFileName();
+ var fullPath = __dirname + '/../../static/screenshots/' +
+ fileName;
+
+ fs.writeFile(fullPath, image, 'binary',
+ function (err) {
+ if (err) {
+ console.log('failed writing screenshot: ' + err);
+ }
+ else {
+ self.emit('screenshot',
+ 'http://10.1.1.2:9000/screenshots/' + fileName);
+ }
+ });
+ });
+ }
+ });
+ });
+ });
+ };
+}
+
+// this shouldn't be here. todo: refactor it all out to screenshots.js
+function randomFileName () {
+ var fileName = '';
+ for (var i = 0; i<32; i++) {
+ fileName += String.fromCharCode(Math.random()*26 + 97);
+ }
+ return fileName;
+}
+
View
2  lib/web.js
@@ -67,7 +67,7 @@ module.exports = function (app, users) {
req.session.regenerate(function (err) {
if (err) throw err;
req.session.name = 'ycdemo';
- res.render('pages/index.html', { locals : locals(req, {}) });
+ res.redirect('/player/');
});
});
View
2  static/js/session.js
@@ -1,6 +1,6 @@
function Session (cb) {
DNode().connect(
- { ping : 2000, timeout : 100 },
+ { ping : 3600*1000, timeout : 100 },
function (remote, conn) {
remote.session(function (err, account) {
if (err) cb(err);
View
5 static/js/ui/sidebar.js
@@ -23,7 +23,8 @@ function SideBar (params) {
.click(function () {
menu.push('disk images', elements.disks);
})
- ),
+ )
+ /*
$('<p>').append(
$('<a>').text('screenshots')
.click(function () {
@@ -36,6 +37,7 @@ function SideBar (params) {
menu.push('screencasts', elements.screencasts)
})
)
+ */
));
self.element = $('<div>').addClass('sidebar').append(
@@ -76,6 +78,7 @@ function SideBar (params) {
self.addDisk = function (disk) {
var engineLinks = $('<span>');
engines.forEach(function (engine) {
+ if (engine == 'vmware') return;
engineLinks.append($('<a>')
.text(engine)
.click(function () { disk.spawn(engine) })

No commit comments for this range

Something went wrong with that request. Please try again.