Skip to content

Commit

Permalink
Merge pull request #453 from tessel/jon-root
Browse files Browse the repository at this point in the history
Adds root command
  • Loading branch information
johnnyman727 committed Nov 24, 2015
2 parents 36aa6d0 + 72d7a83 commit caa2afa
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 0 deletions.
6 changes: 6 additions & 0 deletions bin/tessel-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@ makeCommand('ap')
}
});

makeCommand('root')
.callback(function(opts) {
callControllerWith('root', opts);
})
.help('Gain SSH root access to one of your authorized tessels');


module.exports = function(args) {
parser.parse(args);
Expand Down
29 changes: 29 additions & 0 deletions lib/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,35 @@ controller.disableAccessPoint = function(opts) {
});
};

/*
The T2 root command is used to login into the Tessel's root shell.
*/
controller.root = function(opts) {
// Only give us LAN connections
opts.lan = true;
// We must already be authorized
opts.authorized = true;
return controller.standardTesselCommand(opts, function(tessel) {
logs.info('Starting SSH Session on Tessel.');
return new Promise(function(resolve, reject) {
tessel.lanConnection.ssh.shell(function(err, stream) {
if (err) {
return reject(err);
}
// Stream output to the console
stream.stdout.pipe(process.stdout);
// Stream errors to the console
stream.stderr.pipe(process.stderr);
// Pipe input to the remote process
process.stdin.pipe(stream.stdin);

// Once the session completes, resolve the process
stream.on('close', resolve);
});
});
});
};

controller.printAvailableUpdates = function() {
return updates.requestBuildList().then(function(builds) {
logs.info('Latest builds:');
Expand Down
32 changes: 32 additions & 0 deletions test/unit/bin-tessel-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,38 @@ exports['Tessel (cli: wifi)'] = {
},
};

exports['Tessel (cli: root)'] = {
setUp: function(done) {
this.sandbox = sinon.sandbox.create();
this.warn = this.sandbox.stub(logs, 'warn');
this.info = this.sandbox.stub(logs, 'info');
this.root = this.sandbox.stub(controller, 'root').returns(Promise.resolve());
this.successfulCommand = this.sandbox.stub(cli, 'closeSuccessfulCommand');
done();
},

tearDown: function(done) {
this.sandbox.restore();
done();
},

callThrough: function(test) {
test.expect(2);

var resolve = Promise.resolve();
this.root.returns(resolve);

cli(['root']);

resolve.then(function() {
test.equal(this.root.callCount, 1);
test.equal(this.successfulCommand.callCount, 1);
test.done();
}.bind(this));
},

};

exports['closeFailedCommand'] = {
setUp: function(done) {
this.sandbox = sinon.sandbox.create();
Expand Down
111 changes: 111 additions & 0 deletions test/unit/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -838,3 +838,114 @@ exports['controller.closeTesselConnections'] = {
});
},
};

exports['controller.root'] = {
setUp: function(done) {
this.sandbox = sinon.sandbox.create();
this.logsWarn = this.sandbox.stub(logs, 'warn', function() {});
this.logsInfo = this.sandbox.stub(logs, 'info', function() {});
this.logsBasic = this.sandbox.stub(logs, 'basic', function() {});

this.standardTesselCommand = this.sandbox.stub(controller, 'standardTesselCommand').returns(Promise.resolve());
done();
},

tearDown: function(done) {
this.sandbox.restore();
done();
},

setsOptsLanTrue: function(test) {
test.expect(3);

var opts = {};

controller.root(opts)
.then(function() {
var options = this.standardTesselCommand.lastCall.args[0];

test.equal(this.standardTesselCommand.callCount, 1);
test.equal(options, opts);
test.equal(options.lan, true);
test.done();
}.bind(this));
},

setsAuthorizedTrue: function(test) {
test.expect(3);

var opts = {};

controller.root(opts)
.then(function() {
var options = this.standardTesselCommand.lastCall.args[0];

test.equal(this.standardTesselCommand.callCount, 1);
test.equal(options, opts);
test.equal(options.authorized, true);
test.done();
}.bind(this));
},

openShell: function(test) {
test.expect(6);

var sandbox = this.sandbox;
var tessel = newTessel({
authorized: true,
sandbox: sandbox,
type: 'LAN',
});

function S() {
this.stdout = {
pipe: sandbox.spy()
};
this.stderr = {
pipe: sandbox.spy()
};
this.stdin = {
pipe: sandbox.spy()
};
}

S.prototype = Object.create(Emitter.prototype);

var stream = new S();

tessel.lanConnection.ssh = {};
tessel.lanConnection.ssh.shell = function() {};

this.shell = this.sandbox.stub(tessel.lanConnection.ssh, 'shell', function(callback) {
process.nextTick(function() {
callback(null, stream);
});
});

this.standardTesselCommand.restore();
this.standardTesselCommand = this.sandbox.stub(controller, 'standardTesselCommand', function(opts, callback) {
return callback(tessel);
}.bind(this));


this.processStdin = this.sandbox.stub(process.stdin, 'pipe');

controller.root({})
.then(function() {

test.equal(stream.stdout.pipe.callCount, 1);
test.equal(stream.stderr.pipe.callCount, 1);
test.equal(process.stdin.pipe.callCount, 1);

test.equal(stream.stdout.pipe.lastCall.args[0], process.stdout);
test.equal(stream.stderr.pipe.lastCall.args[0], process.stderr);
test.equal(process.stdin.pipe.lastCall.args[0], stream.stdin);

test.done();
}.bind(this));

setImmediate(function() {
stream.emit('close');
});
},
};

0 comments on commit caa2afa

Please sign in to comment.