Display image checksum on success in the CLI (#417)

* Upgrade etcher-image-write to v5.0.0

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>

* Display image CRC32 checksum on success

Fixes: http://github.com/resin-io/etcher/issues/357
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
Juan Cruz Viotti 2016-05-19 10:13:10 -04:00
parent 198d24741a
commit e1a3c88b10
11 changed files with 130 additions and 26 deletions

View File

@ -5938,6 +5938,10 @@ html {
margin-top: 15px; margin-top: 15px;
margin-bottom: 15px; } margin-bottom: 15px; }
.space-vertical-small {
margin-top: 10px;
margin-bottom: 10px; }
.space-top-medium { .space-top-medium {
margin-top: 15px; } margin-top: 15px; }
@ -5951,6 +5955,32 @@ html {
.space-right-tiny { .space-right-tiny {
margin-right: 5px; } margin-right: 5px; }
/*
* Copyright 2016 Resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.label {
font-size: 11px;
font-weight: normal;
padding: 8px 25px; }
.label-default {
background-color: #3e4147;
color: #919191; }
.label-default > b {
color: #f2f2f2; }
/* /*
* Copyright 2016 Resin.io * Copyright 2016 Resin.io
* *
@ -6428,6 +6458,9 @@ button.btn:focus, button.progress-button:focus {
.page-settings .checkbox input[type="checkbox"]:not(:checked) + * { .page-settings .checkbox input[type="checkbox"]:not(:checked) + * {
color: #ddd; } color: #ddd; }
.monospace {
font-family: monospace; }
.icon-caption { .icon-caption {
margin-top: 10px; } margin-top: 10px; }
.icon-caption[disabled] { .icon-caption[disabled] {
@ -6436,6 +6469,9 @@ button.btn:focus, button.progress-button:focus {
.block { .block {
display: block; } display: block; }
.inline-block {
display: inline-block; }
body { body {
letter-spacing: 1px; } letter-spacing: 1px; }

View File

@ -85,26 +85,25 @@ form.run([
} }
}); });
}).then(function(success) { }).then(function(results) {
if (options.robot) { if (options.robot) {
console.log(`done ${success}`); console.log(`done ${results.passedValidation} ${results.sourceChecksum}`);
} else if (options.ipc) { } else if (options.ipc) {
process.send({ process.send({
command: 'done', command: 'done',
data: { data: results
success: success
}
}); });
} else { } else {
if (success) { if (results.passedValidation) {
console.log('Your flash is complete!'); console.log('Your flash is complete!');
console.log(`Checksum: ${results.sourceChecksum}`);
} else { } else {
console.error('Validation failed!'); console.error('Validation failed!');
} }
} }
if (success) { if (results.passedValidation) {
process.exit(EXIT_CODES.SUCCESS); process.exit(EXIT_CODES.SUCCESS);
} else { } else {
process.exit(EXIT_CODES.VALIDATION_ERROR); process.exit(EXIT_CODES.VALIDATION_ERROR);
@ -114,6 +113,11 @@ form.run([
if (options.robot) { if (options.robot) {
console.error(error.message); console.error(error.message);
} else if (options.ipc) {
process.send({
command: 'error',
data: error
});
} else { } else {
utils.printError(error); utils.printError(error);
} }

View File

@ -258,16 +258,18 @@ app.controller('AppController', function(
device: drive.device device: drive.device
}); });
return self.writer.flash(image, drive).then(function(success) { return self.writer.flash(image, drive).then(function(results) {
// TODO: Find a better way to manage flash/check // TODO: Find a better way to manage flash/check
// success/error state than a global boolean flag. // success/error state than a global boolean flag.
self.success = success; self.success = results.passedValidation;
if (self.success) { if (self.success) {
OSNotificationService.send('Success!', 'Your flash is complete'); OSNotificationService.send('Success!', 'Your flash is complete');
AnalyticsService.logEvent('Done'); AnalyticsService.logEvent('Done');
$state.go('success'); $state.go('success', {
checksum: results.sourceChecksum
});
} else { } else {
OSNotificationService.send('Oops!', 'Looks like your flash has failed'); OSNotificationService.send('Oops!', 'Looks like your flash has failed');
AnalyticsService.logEvent('Validation error'); AnalyticsService.logEvent('Validation error');

View File

@ -106,7 +106,7 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
* @param {Object} drive - drive * @param {Object} drive - drive
* @param {Function} onProgress - in progress callback (state) * @param {Function} onProgress - in progress callback (state)
* *
* @fulfil {Boolean} - whether the operation succeeded * @fulfil {Object} - flash results
* @returns {Promise} * @returns {Promise}
* *
* @example * @example
@ -165,23 +165,30 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
}); });
child.on('message', function(message) { child.on('message', function(message) {
if (message.command === 'progress') { switch (message.command) {
return onProgress(message.data); case 'progress': {
onProgress(message.data);
break;
}
case 'done': {
resolve(message.data);
break;
}
case 'error': {
reject(message.data);
break;
}
} }
}); });
child.on('error', reject); child.on('error', reject);
child.on('close', function(code) { child.on('close', function(code) {
if (code === EXIT_CODES.SUCCESS) { if (code !== EXIT_CODES.SUCCESS && code !== EXIT_CODES.VALIDATION_ERROR) {
return resolve(true); return reject(new Error(`Child process exitted with error code: ${code}`));
} }
if (code === EXIT_CODES.VALIDATION_ERROR) {
return resolve(false);
}
return reject(new Error(`Child process exitted with error code: ${code}`));
}); });
}); });
}; };
@ -197,6 +204,7 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
* @param {String} image - image path * @param {String} image - image path
* @param {Object} drive - drive * @param {Object} drive - drive
* *
* @fulfil {Object} flash results
* @returns {Promise} * @returns {Promise}
* *
* @example * @example

View File

@ -16,7 +16,7 @@
'use strict'; 'use strict';
module.exports = function($state, SelectionStateModel, ImageWriterService, AnalyticsService, SettingsModel) { module.exports = function($state, $stateParams, SelectionStateModel, ImageWriterService, AnalyticsService, SettingsModel) {
/** /**
* @summary Settings data * @summary Settings data
@ -25,6 +25,13 @@ module.exports = function($state, SelectionStateModel, ImageWriterService, Analy
*/ */
this.settings = SettingsModel.data; this.settings = SettingsModel.data;
/**
* @summary Route params
* @type Object
* @public
*/
this.params = $stateParams;
/** /**
* @summary Restart the flashing process * @summary Restart the flashing process
* @function * @function

View File

@ -41,7 +41,7 @@ FinishPage.controller('FinishController', require('./controllers/finish'));
FinishPage.config(function($stateProvider) { FinishPage.config(function($stateProvider) {
$stateProvider $stateProvider
.state('success', { .state('success', {
url: '/success', url: '/success/:checksum',
controller: 'FinishController as finish', controller: 'FinishController as finish',
templateUrl: './pages/finish/templates/success.tpl.html' templateUrl: './pages/finish/templates/success.tpl.html'
}); });

View File

@ -2,9 +2,9 @@
<div class="col-xs"> <div class="col-xs">
<div class="box text-center"> <div class="box text-center">
<h3><span class="tick tick--success" class="space-right-tiny"></span> Flash Complete!</h3> <h3><span class="tick tick--success" class="space-right-tiny"></span> Flash Complete!</h3>
<p class="soft space-vertical-medium" ng-show="finish.settings.unmountOnSuccess">Safely ejected and ready for use</p> <p class="soft space-vertical-small" ng-show="finish.settings.unmountOnSuccess">Safely ejected and ready for use</p>
<div class="row center-xs space-vertical-large"> <div class="row center-xs space-vertical-medium">
<div class="col-xs-4 space-medium"> <div class="col-xs-4 space-medium">
<div class="box"> <div class="box">
<p class="soft button-label">Would you like to flash the same image?</p> <p class="soft button-label">Would you like to flash the same image?</p>
@ -27,6 +27,8 @@
</div> </div>
</div> </div>
</div> </div>
<span class="inline-block label label-default">CRC32 CHECKSUM : <b class="monospace">{{ ::finish.params.checksum }}</b></span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,30 @@
/*
* Copyright 2016 Resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.label {
font-size: 11px;
font-weight: normal;
padding: 8px 25px;
}
.label-default {
background-color: #3e4147;
color: darken($gray-light, 30%);
> b {
color: darken(white, 5%);
}
}

View File

@ -37,6 +37,7 @@ $alert-padding: 13px;
@import "./modules/bootstrap"; @import "./modules/bootstrap";
@import "./modules/space"; @import "./modules/space";
@import "./components/label";
@import "./components/badge"; @import "./components/badge";
@import "./components/caption"; @import "./components/caption";
@import "./components/button"; @import "./components/button";
@ -49,6 +50,10 @@ $alert-padding: 13px;
@import "../components/svg-icon/styles/svg-icon"; @import "../components/svg-icon/styles/svg-icon";
@import "../pages/settings/styles/settings"; @import "../pages/settings/styles/settings";
.monospace {
font-family: monospace;
}
.icon-caption { .icon-caption {
@extend .caption; @extend .caption;
@extend .center-block; @extend .center-block;
@ -64,6 +69,10 @@ $alert-padding: 13px;
display: block; display: block;
} }
.inline-block {
display: inline-block;
}
body { body {
letter-spacing: 1px; letter-spacing: 1px;
} }

View File

@ -16,6 +16,7 @@
$spacing-large: 30px; $spacing-large: 30px;
$spacing-medium: 15px; $spacing-medium: 15px;
$spacing-small: 10px;
$spacing-tiny: 5px; $spacing-tiny: 5px;
.space-medium { .space-medium {
@ -27,6 +28,11 @@ $spacing-tiny: 5px;
margin-bottom: $spacing-medium; margin-bottom: $spacing-medium;
} }
.space-vertical-small {
margin-top: $spacing-small;
margin-bottom: $spacing-small;
}
.space-top-medium { .space-top-medium {
margin-top: $spacing-medium; margin-top: $spacing-medium;
} }

View File

@ -56,7 +56,7 @@
"drivelist": "^3.0.0", "drivelist": "^3.0.0",
"electron-is-running-in-asar": "^1.0.0", "electron-is-running-in-asar": "^1.0.0",
"etcher-image-stream": "^1.2.0", "etcher-image-stream": "^1.2.0",
"etcher-image-write": "^4.0.2", "etcher-image-write": "^5.0.0",
"flexboxgrid": "^6.3.0", "flexboxgrid": "^6.3.0",
"is-elevated": "^1.0.0", "is-elevated": "^1.0.0",
"lodash": "^4.5.1", "lodash": "^4.5.1",