Skip to content

Commit

Permalink
Refactored simple execs
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyman727 committed Oct 1, 2015
1 parent c31d9cc commit 5455273
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 334 deletions.
2 changes: 1 addition & 1 deletion lib/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ controller.renameTessel = function(opts) {
if (!opts.reset && !opts.newName) {
reject('A new name must be provided.');
} else {
if (!Tessel.isValidName(opts.newName)) {
if (!opts.reset && !Tessel.isValidName(opts.newName)) {
reject('Invalid name: ' + opts.newName + '. The name must be a valid hostname string. See http://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names.');
} else {
resolve();
Expand Down
51 changes: 19 additions & 32 deletions lib/tessel/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,44 +68,31 @@ Tessel.prototype.restartScript = function(opts) {
var filepath = isPush ? PUSH_PATH : RUN_PATH;

return new Promise(function(resolve, reject) {
return self.connection.exec(commands.readFile(filepath + opts.entryPoint))
.then(function(remoteProcess) {
var error = '';

remoteProcess.stderr.on('data', function(data) {
error += data.toString();
});

remoteProcess.once('close', function() {
if (error.length) {
if (error.indexOf('No such file or directory') !== -1) {
error = '"' + opts.entryPoint + '" not found on ' + self.name;
}
return self.simpleExec(commands.readFile(filepath + opts.entryPoint))
.then(function() {
if (isPush) {
// Start the script from flash memory
return actions.startPushedScript(self, opts.entryPoint)
.then(resolve).catch(reject);
} else {
// Start the script in RAM
return actions.runScript(self, filepath, opts.entryPoint)
.then(resolve).catch(reject);
}
})
.catch(function(error) {
if (error.message.indexOf('No such file or directory') !== -1) {
error = '"' + opts.entryPoint + '" not found on ' + self.name;
}

return reject(error);
} else {
if (isPush) {
// Start the script from flash memory
actions.startPushedScript(self, opts.entryPoint)
.then(resolve).catch(reject);
} else {
// Start the script in RAM
actions.runScript(self, filepath, opts.entryPoint)
.then(resolve).catch(reject);
}
}
});
return reject(error);
});
});
};

actions.execRemoteCommand = function(tessel, command, filepath) {
return new Promise(function(resolve) {
return tessel.connection.exec(commands[command](filepath))
.then(function(remoteProcess) {
remoteProcess.once('close', resolve);
});
});
return tessel.simpleExec(commands[command](filepath))
.catch(function() {});
};

actions.findProject = function(opts) {
Expand Down
44 changes: 14 additions & 30 deletions lib/tessel/erase.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,20 @@ Tessel.prototype.eraseScript = function() {
return new Promise(function(resolve, reject) {

logs.info('Erasing files from Flash...');
// Stop processes and delete everything in the folder
return self.connection.exec(commands.stopRunningScript())
.then(function(remoteProcess) {

// Buffer to store incoming error data
var errBuf = new Buffer(0);
//If we receive error data (which we would if there is no script running)
remoteProcess.stderr.on('data', function(e) {
// Concatenate the data
errBuf = Buffer.concat([errBuf, e]);
});
// Once the process completes
remoteProcess.once('close', function() {
// Check if an error occurred
if (errBuf.length) {
// If we get a notice that the command failed
if (errBuf.toString().indexOf('Command failed') !== -1) {
// Let the user know what went wrong
reject('No files have been pushed. Run `tessel push FILE` to push to Flash.');
} else {
// Otherwise this is an unexpected error
reject('An unexpected error occurred:' + errBuf.toString());
}
}
// Assume it worked if there was no error
else {
logs.info('Files erased.');
resolve();
}
});
return self.simpleExec(commands.stopRunningScript())
.then(function stopped() {
logs.info('Files erased.');
return resolve();
})
.catch(function(error) {
// If we get a notice that the command failed
if (error.message.indexOf('Command failed') !== -1) {
// Let the user know what went wrong
return reject('No files have been pushed. Run `tessel push FILE` to push to Flash.');
} else {
// Otherwise this is an unexpected error
return reject('An unexpected error occurred:' + error.message);
}
});
});
};
128 changes: 37 additions & 91 deletions lib/tessel/name.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,13 @@ Tessel.isValidName = function(value) {
};

Tessel.prototype.getName = function() {
var self = this;
return new Promise(function(resolve) {
// Ask for the hostname from the remote device
return self.connection.exec(commands.getHostname())
.then(function(remoteProc) {
// Var to hold the state of the name
var name = '';
// Print any errors to the console
remoteProc.stderr.pipe(process.stderr);

// When we receive data
remoteProc.stdout.on('data', function(d) {
// Add it to the name string
name += d.toString();
});

// When the process completes
remoteProc.stdout.once('end', function() {
// Remove any trailing newlines and set the internal variable
self.name = name.replace(/^\s+|\s+$/g, '');
// Return the name
return resolve(self.name);
});
});
});
return this.simpleExec(commands.getHostname())
.then(function nameFound(name) {
// Remove any trailing newlines and set the internal variable
this.name = name.replace(/^\s+|\s+$/g, '');
// Return the name
return this.name;
}.bind(this));
};

Tessel.prototype.setName = function(name) {
Expand All @@ -47,36 +29,24 @@ Tessel.prototype.setName = function(name) {
return reject('Invalid name.');
}
// Write the new hostname to the device
return self.connection.exec(commands.setHostname(name))
.then(function(remoteProc) {
// Pipe stderr of the remote process to this Node process stderr
remoteProc.stderr.pipe(process.stderr);
// Once the process completes
remoteProc.once('close', function() {
// Commit the new hostname
return self.connection.exec(commands.commitHostname())
.then(function(remoteProc) {
// Pipe stderr of the remote process to this Node process stderr
remoteProc.stderr.pipe(process.stderr);
// When the process completes the name has been set
remoteProc.once('close', function() {
// Write the new name to the kernel hostname as well (so it reports the proper name in the terminal)
return self.connection.exec(commands.openStdinToFile('/proc/sys/kernel/hostname'))
.then(function(remoteProc) {
// Pipe stderr of the remote process to this Node process stderr
// call it when this process finishes
remoteProc.once('close', function() {
// Reset MDNS so it advertises with the new name
return self.resetMDNS()
.then(resolve);
});
// Write the new name to the stdin
remoteProc.stdin.end(name);
});
});
});
});
});
return self.simpleExec(commands.setHostname(name))
.then(function hostnameSet() {
// Commit the new hostname
return self.simpleExec(commands.commitHostname());
})
.then(function hostnameCommitted() {
// Write the new name to the kernel hostname as well (so it reports the proper name in the terminal)
return self.connection.exec(commands.openStdinToFile('/proc/sys/kernel/hostname'))
.then(function(remoteProc) {
remoteProc.stdin.end(name);
});
})
// Reset MDNS so it advertises with the new name
.then(function kernelWritten() {
return self.resetMDNS()
.then(resolve);
})
.catch(reject);
});
};

Expand Down Expand Up @@ -127,40 +97,16 @@ Tessel.prototype.rename = function(opts) {
};

Tessel.prototype._getMACAddress = function() {
var self = this;
return new Promise(function(resolve) {
// Fetch details about the eth0 interface
return self.connection.exec(commands.getInterface('eth0'))
.then(function(remoteProc) {

// Report any issues
remoteProc.stderr.pipe(process.stderr);

// Var to store incoming chunks of interface information
var info = '';

// Once we finish receiving data
remoteProc.once('close', function() {

// Capture the mac address out of the info using a regexp
// Fun fact: lookbehinds aren't supported in JS
var macAddr = info.match(/(?:HWaddr )(.*)/)[1];

// Remove any newlines
macAddr = macAddr.replace(/^\s+|\s+$/g, '');

// Remove colons, for ex 02:A3:03:3B:47:04 -> 02A3033B4704
macAddr = macAddr.replace(/:/g, '');

// Return the mac addres
resolve(macAddr);
});

// When we receive data on stdout
remoteProc.stdout.on('data', function(data) {
// add it to the contatenated string
info += data.toString();
});
});
});
return this.simpleExec(commands.getInterface('eth0'))
.then(function fetchedInterface(interfaceInfo) {
// Capture the mac address out of the info using a regexp
// Fun fact: lookbehinds aren't supported in JS
var macAddr = interfaceInfo.match(/(?:HWaddr )(.*)/)[1];

// Remove any newlines
macAddr = macAddr.replace(/^\s+|\s+$/g, '');

// Remove colons, for ex 02:A3:03:3B:47:04 -> 02A3033B4704
return macAddr.replace(/:/g, '');
});
};
79 changes: 13 additions & 66 deletions lib/tessel/provision.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,77 +140,24 @@ actions.authTessel = function(tessel, filepath) {
};

actions.checkAuthFileExists = function(tessel, authFile) {
return new Promise(function(resolve, reject) {
// Ensure that the remote authorized_keys file exists
return tessel.connection.exec(commands.ensureFileExists(authFile))
.then(function(remoteProc) {

// Var to store incoming error data
var errBuf = '';

// If we get incoming data
remoteProc.stderr.on('data', function(data) {
// Concat it
errBuf += data.toString();
});

// Once this process completes
remoteProc.once('close', function() {
// Check if there was an error
if (errBuf.length) {
// If there was, report it
reject(errBuf);
}
// Otherwise, continue
else {
resolve();
}
});
});
});
// Ensure that the remote authorized_keys file exists
return tessel.simpleExec(commands.ensureFileExists(authFile));
};

function checkIfKeyInFile(tessel, authFile, pubKey) {
return new Promise(function(resolve, reject) {
// Read the public keys from the auth file
return tessel.connection.exec(commands.readFile(authFile))
.then(function(remoteProc) {
// Var to hold pub key data
var dataBuf = '';
// Var to hold any emitted errors
var errBuf = '';

// When stderr data is returned
remoteProc.stderr.on('data', function(err) {
// concat it until the process closes
errBuf += err.toString();
});

// When we get data
remoteProc.stdout.on('data', function(data) {
// concat it until the process closes
dataBuf += data.toString();
});

// When the process closes
remoteProc.once('close', function() {
// Check if an error was reported
if (errBuf.length) {
return reject(errBuf);
}
// If there were no errors
else {
// If keys on the remote device contain our key
if (dataBuf.indexOf(pubKey) > -1) {
// Report that the key already exists
return reject(new AlreadyAuthenticatedError());
}
// Otherwise, the key needs to be added
else {
return resolve();
}
}
});
return tessel.simpleExec(commands.readFile(authFile))
.then(function fileRead(fileContents) {
// If keys on the remote device contain our key
if (fileContents.indexOf(pubKey) > -1) {
// Report that the key already exists
return reject(new AlreadyAuthenticatedError());
}
// Otherwise, the key needs to be added
else {
return resolve();
}
});
});
}
Expand Down

0 comments on commit 5455273

Please sign in to comment.