Skip to content

Commit

Permalink
Adds USB updating and options for local binary paths
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyman727 committed Apr 12, 2016
1 parent e7860cc commit 181e098
Show file tree
Hide file tree
Showing 8 changed files with 571 additions and 306 deletions.
11 changes: 11 additions & 0 deletions bin/tessel-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,17 @@ makeCommand('update')
flag: true,
help: 'Update to the latest version regardless of current version.'
})
.option('openwrt-path', {
abbr: 'op',
required: false,
flag: false,
help: 'Update with the OpenWRT image at the indicated local path.'
})
.option('firmware-path', {
abbr: 'fp',
required: false,
help: 'Update with the firmware image at the indicated local path.'
})
.callback(function(opts) {
if (opts.list) {
callControllerWith('printAvailableUpdates');
Expand Down
189 changes: 98 additions & 91 deletions lib/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -808,117 +808,124 @@ controller.printAvailableUpdates = function() {

controller.update = function(opts) {
opts.authorized = true;
opts.lanPrefer = true;
return controller.standardTesselCommand(opts, function(tessel) {
return new Promise(function updateProcess(resolve, reject) {
// If it's not connected via USB, we can't update it
if (!tessel.usbConnection) {
return reject('Must have Tessel connected over USB to complete update. Aborting update.');
}

// // If this Tessel isn't connected to the LAN
if (!tessel.lanConnection || !tessel.lanConnection.authorized) {
// Reject because USB updates are broken...
return reject('No LAN connection found. USB-only updates do not work yet. Please ensure Tessel is connected to wifi and try again');
}
if (opts.openwrtPath || opts.firmwarePath) {
return controller.updateWithLocalBuilds(opts, tessel);
} else {
return controller.updateWithRemoteBuilds(opts, tessel);
}
});
};

return updates.requestBuildList().then(function(builds) {
controller.updateWithLocalBuilds = function(opts, tessel) {
return updates.loadLocalBinaries(opts)
.then((images) => tessel.update(images))
.then(() => logs.info('Finished updating Tessel with local builds.'));
};

var version = opts.version || 'latest';
var versionFromSHA = Promise.resolve(version);
controller.updateWithRemoteBuilds = function(opts, tessel) {
return new Promise(function updateProcess(resolve, reject) {
// If it's not connected via USB, we can't update it
if (!tessel.usbConnection) {
return reject('Must have Tessel connected over USB to complete update. Aborting update.');
}

// If we aren't forcing, we'll want to get the current SHA on Tessel
if (!opts.force) {
// Once we have the Tessel
// Over-ride the resolved Promise
versionFromSHA = new Promise(function(resolve, reject) {
// Figure out what commit SHA is running on it
return tessel.fetchCurrentBuildInfo()
// Once we have the current SHA, provide the version
.then(function(currentSHA) {
return resolve(updates.findBuild(builds, 'sha', currentSHA));
})
.catch(function(err) {
// If there was an error because the version file doesn't exist
if (err.message.search('No such file or directory') !== -1) {
// Warn the user
logs.warn('Could not find firmware version on', tessel.name);

if (opts.force !== false) {
// Force the update
opts.force = true;
// Notify the user
logs.warn('Forcefully updating...');
// Resolve instead of reject (the string isn't used anywhere)
return resolve('unknown version');
} else {
// Reject because the user specifically did not want to force
return reject(err);
}
return updates.requestBuildList().then(function(builds) {

var version = opts.version || 'latest';
var versionFromSHA = Promise.resolve(version);

// If we aren't forcing, we'll want to get the current SHA on Tessel
if (!opts.force) {
// Once we have the Tessel
// Over-ride the resolved Promise
versionFromSHA = new Promise(function(resolve, reject) {
// Figure out what commit SHA is running on it
return tessel.fetchCurrentBuildInfo()
// Once we have the current SHA, provide the version
.then(function(currentSHA) {
return resolve(updates.findBuild(builds, 'sha', currentSHA));
})
.catch(function(err) {
// If there was an error because the version file doesn't exist
if (err.message.search('No such file or directory') !== -1) {
// Warn the user
logs.warn('Could not find firmware version on', tessel.name);

if (opts.force !== false) {
// Force the update
opts.force = true;
// Notify the user
logs.warn('Forcefully updating...');
// Resolve instead of reject (the string isn't used anywhere)
return resolve('unknown version');
} else {
// Reject because an unknown error occurred
// Reject because the user specifically did not want to force
return reject(err);
}
});
});
}
} else {
// Reject because an unknown error occurred
return reject(err);
}
});
});
}

return versionFromSHA.then(function(currentVersionInfo) {
var build = updates.findBuild(builds, 'version', version);
var verifiedVersion;
// If the update is forced or this version was requested,
// and a valid build exists for the version provided.
if (version && build) {
// Fetch and Update with the requested version
return controller.updateTesselWithVersion(opts.force, tessel, currentVersionInfo.version, build);
return versionFromSHA.then(function(currentVersionInfo) {
var build = updates.findBuild(builds, 'version', version);
var verifiedVersion;
// If the update is forced or this version was requested,
// and a valid build exists for the version provided.
if (version && build) {
// Fetch and Update with the requested version
return controller.updateTesselWithVersion(opts, tessel, currentVersionInfo.version, build);
} else {
// If they have requested the latest firmware
if (version === 'latest') {
build = builds[builds.length - 1];
verifiedVersion = build.version;
} else {
// If they have requested the latest firmware
if (version === 'latest') {
build = builds[builds.length - 1];
// They provided a valid version that matches a known build.
if (build) {
verifiedVersion = build.version;
} else {
// They provided a valid version that matches a known build.
if (build) {
verifiedVersion = build.version;
}
}
}

// If we've reached this point and no verified version has not
// been identified, then we need to abord the operation and
// notify the user.
if (!verifiedVersion) {
return reject('The requested build was not found. Please see the available builds with `t2 update -l`.');
}
// If we've reached this point and no verified version has not
// been identified, then we need to abord the operation and
// notify the user.
if (!verifiedVersion) {
return reject('The requested build was not found. Please see the available builds with `t2 update -l`.');
}

// Check if the current build is the same or newer if this isn't a forced update
if (!opts.force && semver.gte(currentVersionInfo.version, verifiedVersion)) {
// If it's not, close the Tessel connection and print the error message
var message = tessel.name + ' is already on the latest firmware version (' + currentVersionInfo.version + '). You can force an update with "t2 update --force".';
// Check if the current build is the same or newer if this isn't a forced update
if (!opts.force && semver.gte(currentVersionInfo.version, verifiedVersion)) {
// If it's not, close the Tessel connection and print the error message
var message = tessel.name + ' is already on the latest firmware version (' + currentVersionInfo.version + '). You can force an update with "t2 update --force".';

logs.warn(message);
logs.warn(message);

return resolve();
} else {
if (!opts.force) {
// If it is a newer version, let's update...
logs.info('New firmware version found...' + verifiedVersion);
}
return resolve();
} else {
if (!opts.force) {
// If it is a newer version, let's update...
logs.info('New firmware version found...' + verifiedVersion);
}

logs.info('Updating ' + tessel.name + ' to latest version (' + verifiedVersion + ')...');
logs.info('Updating ' + tessel.name + ' to latest version (' + verifiedVersion + ')...');

// Fetch the requested version
return controller.updateTesselWithVersion(opts.force, tessel, currentVersionInfo.version, build);
}
// Fetch the requested version
return controller.updateTesselWithVersion(opts, tessel, currentVersionInfo.version, build);
}
});
})
.then(resolve)
.catch(reject);
});
}
});
})
.then(resolve)
.catch(reject);
});
};

controller.updateTesselWithVersion = function(force, tessel, currentVersion, build) {
controller.updateTesselWithVersion = function(opts, tessel, currentVersion, build) {

// Fetch the requested build
return updates.fetchBuild(build)
Expand All @@ -927,7 +934,7 @@ controller.updateTesselWithVersion = function(force, tessel, currentVersion, bui
return tessel.update(image)
// Log that the update completed
.then(function logCompletion() {
if (!force) {
if (!opts.force) {
logs.info('Updated', tessel.name, 'from ', currentVersion, ' to ', build.version);
} else {
logs.info('Force updated', tessel.name, 'to version', build.version);
Expand Down

0 comments on commit 181e098

Please sign in to comment.