mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-23 11:16:39 +00:00
commit
bab9069dee
@ -37,6 +37,7 @@ const DEFAULT_SETTINGS = {
|
|||||||
errorReporting: true,
|
errorReporting: true,
|
||||||
unmountOnSuccess: true,
|
unmountOnSuccess: true,
|
||||||
validateWriteOnSuccess: true,
|
validateWriteOnSuccess: true,
|
||||||
|
trim: false,
|
||||||
updatesEnabled: packageJSON.updates.enabled && !_.includes([ 'rpm', 'deb' ], packageJSON.packageType),
|
updatesEnabled: packageJSON.updates.enabled && !_.includes([ 'rpm', 'deb' ], packageJSON.packageType),
|
||||||
lastSleptUpdateNotifier: null,
|
lastSleptUpdateNotifier: null,
|
||||||
lastSleptUpdateNotifierVersion: null,
|
lastSleptUpdateNotifierVersion: null,
|
||||||
|
@ -172,7 +172,8 @@ exports.performWrite = (image, drives, onProgress) => {
|
|||||||
uuid: flashState.getFlashUuid(),
|
uuid: flashState.getFlashUuid(),
|
||||||
flashInstanceUuid: flashState.getFlashUuid(),
|
flashInstanceUuid: flashState.getFlashUuid(),
|
||||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess')
|
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||||
|
trim: settings.get('trim')
|
||||||
}
|
}
|
||||||
|
|
||||||
ipc.server.on('fail', ({ device, error }) => {
|
ipc.server.on('fail', ({ device, error }) => {
|
||||||
@ -200,6 +201,7 @@ exports.performWrite = (image, drives, onProgress) => {
|
|||||||
imagePath: image,
|
imagePath: image,
|
||||||
destinations: drives,
|
destinations: drives,
|
||||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||||
|
trim: settings.get('trim'),
|
||||||
unmountOnSuccess: settings.get('unmountOnSuccess')
|
unmountOnSuccess: settings.get('unmountOnSuccess')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -312,6 +314,7 @@ exports.flash = (image, drives) => {
|
|||||||
flashInstanceUuid: flashState.getFlashUuid(),
|
flashInstanceUuid: flashState.getFlashUuid(),
|
||||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||||
|
trim: settings.get('trim'),
|
||||||
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
}
|
}
|
||||||
@ -375,6 +378,7 @@ exports.cancel = () => {
|
|||||||
flashInstanceUuid: flashState.getFlashUuid(),
|
flashInstanceUuid: flashState.getFlashUuid(),
|
||||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||||
|
trim: settings.get('trim'),
|
||||||
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid,
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid,
|
||||||
status: 'cancel'
|
status: 'cancel'
|
||||||
|
@ -43,6 +43,17 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox"
|
||||||
|
tabindex="8"
|
||||||
|
ng-model="settings.currentData.trim"
|
||||||
|
ng-change="settings.toggle('trim')">
|
||||||
|
|
||||||
|
<span>Trim ext{2,3,4} partitions before writing (raw images only)</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
@ -82,12 +82,10 @@ const terminate = (code) => {
|
|||||||
* @example
|
* @example
|
||||||
* handleError(new Error('Something bad happened!'))
|
* handleError(new Error('Something bad happened!'))
|
||||||
*/
|
*/
|
||||||
const handleError = (error) => {
|
const handleError = async (error) => {
|
||||||
ipc.of[IPC_SERVER_ID].emit('error', errors.toJSON(error))
|
ipc.of[IPC_SERVER_ID].emit('error', errors.toJSON(error))
|
||||||
Bluebird.delay(DISCONNECT_DELAY)
|
await Bluebird.delay(DISCONNECT_DELAY)
|
||||||
.then(() => {
|
terminate(EXIT_CODES.GENERAL_ERROR)
|
||||||
terminate(EXIT_CODES.GENERAL_ERROR)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,42 +93,45 @@ const handleError = (error) => {
|
|||||||
* @param {SourceDestination} source - source
|
* @param {SourceDestination} source - source
|
||||||
* @param {SourceDestination[]} destinations - destinations
|
* @param {SourceDestination[]} destinations - destinations
|
||||||
* @param {Boolean} verify - whether to validate the writes or not
|
* @param {Boolean} verify - whether to validate the writes or not
|
||||||
|
* @param {Boolean} trim - whether to trim ext partitions before writing
|
||||||
* @param {Function} onProgress - function to call on progress
|
* @param {Function} onProgress - function to call on progress
|
||||||
* @param {Function} onFail - function to call on fail
|
* @param {Function} onFail - function to call on fail
|
||||||
* @param {Function} onFinish - function to call on finish
|
* @returns {Promise<{ bytesWritten, devices, errors} >}
|
||||||
* @param {Function} onError - function to call on error
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* writeAndValidate(source, destinations, verify, onProgress, onFail, onFinish, onError)
|
* writeAndValidate(source, destinations, verify, onProgress, onFail, onFinish, onError)
|
||||||
*/
|
*/
|
||||||
const writeAndValidate = (source, destinations, verify, onProgress, onFail, onFinish, onError) => {
|
const writeAndValidate = async (source, destinations, verify, trim, onProgress, onFail) => {
|
||||||
return source.getInnerSource()
|
let innerSource = await source.getInnerSource()
|
||||||
.then((innerSource) => {
|
if (trim && (await innerSource.canRead())) {
|
||||||
return sdk.multiWrite.pipeSourceToDestinations(
|
innerSource = new sdk.sourceDestination.ConfiguredSource(
|
||||||
innerSource,
|
innerSource,
|
||||||
destinations,
|
trim,
|
||||||
onFail,
|
|
||||||
onProgress,
|
// Create stream from file-disk (not source stream)
|
||||||
verify
|
true
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
.then(({ failures, bytesWritten }) => {
|
const { failures, bytesWritten } = await sdk.multiWrite.pipeSourceToDestinations(
|
||||||
const result = {
|
innerSource,
|
||||||
bytesWritten,
|
destinations,
|
||||||
devices: {
|
onFail,
|
||||||
failed: failures.size,
|
onProgress,
|
||||||
successful: destinations.length - failures.size
|
verify
|
||||||
},
|
)
|
||||||
errors: []
|
const result = {
|
||||||
}
|
bytesWritten,
|
||||||
for (const [ destination, error ] of failures) {
|
devices: {
|
||||||
error.device = destination.drive.device
|
failed: failures.size,
|
||||||
result.errors.push(error)
|
successful: destinations.length - failures.size
|
||||||
}
|
},
|
||||||
onFinish(result)
|
errors: []
|
||||||
})
|
}
|
||||||
.catch(onError)
|
for (const [ destination, error ] of failures) {
|
||||||
|
error.device = destination.drive.device
|
||||||
|
result.errors.push(error)
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
ipc.connectTo(IPC_SERVER_ID, () => {
|
ipc.connectTo(IPC_SERVER_ID, () => {
|
||||||
@ -159,7 +160,7 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
|||||||
terminate(EXIT_CODES.SUCCESS)
|
terminate(EXIT_CODES.SUCCESS)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipc.of[IPC_SERVER_ID].on('write', (options) => {
|
ipc.of[IPC_SERVER_ID].on('write', async (options) => {
|
||||||
/**
|
/**
|
||||||
* @summary Progress handler
|
* @summary Progress handler
|
||||||
* @param {Object} state - progress state
|
* @param {Object} state - progress state
|
||||||
@ -172,52 +173,20 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
|||||||
|
|
||||||
let exitCode = EXIT_CODES.SUCCESS
|
let exitCode = EXIT_CODES.SUCCESS
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Finish handler
|
|
||||||
* @param {Object} results - Flash results
|
|
||||||
* @example
|
|
||||||
* writer.on('finish', onFinish)
|
|
||||||
*/
|
|
||||||
const onFinish = (results) => {
|
|
||||||
log(`Finish: ${results.bytesWritten}`)
|
|
||||||
results.errors = _.map(results.errors, (error) => {
|
|
||||||
return errors.toJSON(error)
|
|
||||||
})
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('done', { results })
|
|
||||||
Bluebird.delay(DISCONNECT_DELAY)
|
|
||||||
.then(() => {
|
|
||||||
terminate(exitCode)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Abort handler
|
* @summary Abort handler
|
||||||
* @example
|
* @example
|
||||||
* writer.on('abort', onAbort)
|
* writer.on('abort', onAbort)
|
||||||
*/
|
*/
|
||||||
const onAbort = () => {
|
const onAbort = async () => {
|
||||||
log('Abort')
|
log('Abort')
|
||||||
ipc.of[IPC_SERVER_ID].emit('abort')
|
ipc.of[IPC_SERVER_ID].emit('abort')
|
||||||
Bluebird.delay(DISCONNECT_DELAY)
|
await Bluebird.delay(DISCONNECT_DELAY)
|
||||||
.then(() => {
|
terminate(exitCode)
|
||||||
terminate(exitCode)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ipc.of[IPC_SERVER_ID].on('cancel', onAbort)
|
ipc.of[IPC_SERVER_ID].on('cancel', onAbort)
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Error handler
|
|
||||||
* @param {Error} error - error
|
|
||||||
* @example
|
|
||||||
* writer.on('error', onError)
|
|
||||||
*/
|
|
||||||
const onError = (error) => {
|
|
||||||
log(`Error: ${error.message}`)
|
|
||||||
exitCode = EXIT_CODES.GENERAL_ERROR
|
|
||||||
ipc.of[IPC_SERVER_ID].emit('error', errors.toJSON(error))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @summary Failure handler (non-fatal errors)
|
* @summary Failure handler (non-fatal errors)
|
||||||
* @param {SourceDestination} destination - destination
|
* @param {SourceDestination} destination - destination
|
||||||
@ -234,24 +203,36 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const destinations = _.map(options.destinations, 'device')
|
const destinations = _.map(options.destinations, 'device')
|
||||||
const dests = _.map(options.destinations, (destination) => {
|
|
||||||
return new sdk.sourceDestination.BlockDevice(destination, options.unmountOnSuccess)
|
|
||||||
})
|
|
||||||
const source = new sdk.sourceDestination.File(options.imagePath, sdk.sourceDestination.File.OpenFlags.Read)
|
|
||||||
writeAndValidate(
|
|
||||||
source,
|
|
||||||
dests,
|
|
||||||
options.validateWriteOnSuccess,
|
|
||||||
onProgress,
|
|
||||||
onFail,
|
|
||||||
onFinish,
|
|
||||||
onError
|
|
||||||
)
|
|
||||||
|
|
||||||
log(`Image: ${options.imagePath}`)
|
log(`Image: ${options.imagePath}`)
|
||||||
log(`Devices: ${destinations.join(', ')}`)
|
log(`Devices: ${destinations.join(', ')}`)
|
||||||
log(`Umount on success: ${options.unmountOnSuccess}`)
|
log(`Umount on success: ${options.unmountOnSuccess}`)
|
||||||
log(`Validate on success: ${options.validateWriteOnSuccess}`)
|
log(`Validate on success: ${options.validateWriteOnSuccess}`)
|
||||||
|
log(`Trim: ${options.trim}`)
|
||||||
|
const dests = _.map(options.destinations, (destination) => {
|
||||||
|
return new sdk.sourceDestination.BlockDevice(destination, options.unmountOnSuccess)
|
||||||
|
})
|
||||||
|
const source = new sdk.sourceDestination.File(options.imagePath, sdk.sourceDestination.File.OpenFlags.Read)
|
||||||
|
try {
|
||||||
|
const results = await writeAndValidate(
|
||||||
|
source,
|
||||||
|
dests,
|
||||||
|
options.validateWriteOnSuccess,
|
||||||
|
options.trim,
|
||||||
|
onProgress,
|
||||||
|
onFail
|
||||||
|
)
|
||||||
|
log(`Finish: ${results.bytesWritten}`)
|
||||||
|
results.errors = _.map(results.errors, (error) => {
|
||||||
|
return errors.toJSON(error)
|
||||||
|
})
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('done', { results })
|
||||||
|
await Bluebird.delay(DISCONNECT_DELAY)
|
||||||
|
terminate(exitCode)
|
||||||
|
} catch (error) {
|
||||||
|
log(`Error: ${error.message}`)
|
||||||
|
exitCode = EXIT_CODES.GENERAL_ERROR
|
||||||
|
ipc.of[IPC_SERVER_ID].emit('error', errors.toJSON(error))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipc.of[IPC_SERVER_ID].on('connect', () => {
|
ipc.of[IPC_SERVER_ID].on('connect', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user