mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 23:37:18 +00:00
fix(usbboot): Move blob handling to SDK
This moves the usbboot blob handling into the SDK to avoid root dirname conflicts through shimmed __dirname in bundled UI and different contexts of execution. Change-Type: patch
This commit is contained in:
parent
3bac0225e5
commit
4c8b97afb3
@ -16,28 +16,9 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
const _ = require('lodash')
|
||||
const Bluebird = require('bluebird')
|
||||
const fs = Bluebird.promisifyAll(require('fs'))
|
||||
const path = require('path')
|
||||
const settings = require('../models/settings')
|
||||
const SDK = require('../../../sdk')
|
||||
const permissions = require('../../../shared/permissions')
|
||||
const packageJSON = require('../../../../package.json')
|
||||
|
||||
/**
|
||||
* @summary The Etcher "blobs" directory path
|
||||
* @type {String}
|
||||
* @constant
|
||||
*/
|
||||
let BLOBS_DIRECTORY = path.join(__dirname, '..', '..', '..', 'blobs')
|
||||
|
||||
// FIXME: When bundled & packaged, the blob path differs
|
||||
if (packageJSON.packageType !== 'local') {
|
||||
BLOBS_DIRECTORY = packageJSON.packageType === 'AppImage'
|
||||
? 'bin/resources/app.asar/lib/blobs'
|
||||
: path.join(__dirname, '..', '..', 'blobs')
|
||||
}
|
||||
|
||||
const scanner = SDK.createScanner({
|
||||
blockdevice: {
|
||||
@ -45,19 +26,7 @@ const scanner = SDK.createScanner({
|
||||
return settings.get('unsafeMode')
|
||||
}
|
||||
},
|
||||
usbboot: {
|
||||
readFile: (name) => {
|
||||
const isRaspberryPi = _.includes([
|
||||
'bootcode.bin',
|
||||
'start_cd.elf',
|
||||
'fixup_cd.dat'
|
||||
], name)
|
||||
|
||||
const blobPath = isRaspberryPi ? path.join('raspberrypi', name) : name
|
||||
|
||||
return fs.readFileAsync(path.join(BLOBS_DIRECTORY, 'usbboot', blobPath))
|
||||
}
|
||||
}
|
||||
usbboot: {}
|
||||
})
|
||||
|
||||
// NOTE: Enable USBBoot on Linux if run as root
|
||||
|
@ -21,6 +21,14 @@ const Bluebird = require('bluebird')
|
||||
const EventEmitter = require('events')
|
||||
const drivelist = Bluebird.promisifyAll(require('drivelist'))
|
||||
|
||||
const USBBOOT_RPI_COMPUTE_MODULE_NAMES = [
|
||||
'0001',
|
||||
'RPi-MSD- 0001',
|
||||
'File-Stor Gadget',
|
||||
'Linux File-Stor Gadget USB Device',
|
||||
'Linux File-Stor Gadget Media'
|
||||
]
|
||||
|
||||
/**
|
||||
* @summary BlockDeviceAdapter
|
||||
* @class
|
||||
@ -68,7 +76,7 @@ class BlockDeviceAdapter extends EventEmitter {
|
||||
// TODO: Find a better way to detect that a certain
|
||||
// block device is a compute module initialized
|
||||
// through usbboot.
|
||||
if (_.includes([ '0001', 'RPi-MSD- 0001', 'File-Stor Gadget', 'Linux File-Stor Gadget USB Device' ], drive.description)) {
|
||||
if (_.includes(USBBOOT_RPI_COMPUTE_MODULE_NAMES, drive.description)) {
|
||||
drive.description = 'Compute Module'
|
||||
drive.icon = 'raspberrypi'
|
||||
drive.isSystem = false
|
||||
|
@ -22,6 +22,8 @@
|
||||
'use strict'
|
||||
|
||||
const _ = require('lodash')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const EventEmitter = require('events')
|
||||
const Bluebird = require('bluebird')
|
||||
const debug = require('debug')('etcher:sdk:usbboot')
|
||||
@ -212,7 +214,6 @@ class USBBootAdapter extends EventEmitter {
|
||||
* @private
|
||||
*
|
||||
* @param {String} name - blob name
|
||||
* @param {Function} fallback - fallback function
|
||||
* @fulfil {Buffer} - blob
|
||||
* @returns {Promise}
|
||||
*
|
||||
@ -220,16 +221,14 @@ class USBBootAdapter extends EventEmitter {
|
||||
* const Bluebird = require('bluebird')
|
||||
* const fs = Bluebird.promisifyAll(require('fs'))
|
||||
*
|
||||
* const blob = adapter.queryBlobFromCache('start.elf', (name) => {
|
||||
* return fs.readFileAsync(path.join('./blobs', name))
|
||||
* })
|
||||
* const blob = adapter.queryBlobFromCache('start.elf')
|
||||
*/
|
||||
queryBlobFromCache (name, fallback) {
|
||||
queryBlobFromCache (name) {
|
||||
if (this.blobCache[name]) {
|
||||
return Bluebird.resolve(this.blobCache[name])
|
||||
}
|
||||
|
||||
return fallback(name).tap((buffer) => {
|
||||
return USBBootAdapter.readBlob(name).tap((buffer) => {
|
||||
this.blobCache[name] = buffer
|
||||
})
|
||||
}
|
||||
@ -302,9 +301,7 @@ class USBBootAdapter extends EventEmitter {
|
||||
}
|
||||
|
||||
if (_.isNil(this.progress[result.raw])) {
|
||||
this.prepare(device, {
|
||||
readFile: options.readFile
|
||||
}).catch((error) => {
|
||||
this.prepare(device).catch((error) => {
|
||||
this.emit('error', error)
|
||||
})
|
||||
}
|
||||
@ -337,8 +334,6 @@ class USBBootAdapter extends EventEmitter {
|
||||
* @private
|
||||
*
|
||||
* @param {Object} device - node-usb device
|
||||
* @param {Object} options - options
|
||||
* @param {Function} options.readFile - read file function
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
@ -352,7 +347,7 @@ class USBBootAdapter extends EventEmitter {
|
||||
* console.log('Done!')
|
||||
* })
|
||||
*/
|
||||
prepare (device, options) {
|
||||
prepare (device) {
|
||||
/**
|
||||
* @summary Set device progress
|
||||
* @function
|
||||
@ -416,7 +411,7 @@ class USBBootAdapter extends EventEmitter {
|
||||
const endpoint = deviceInterface.endpoint(addresses.endpoint)
|
||||
|
||||
if (serialNumberIndex === USB_DESCRIPTOR_NULL_INDEX) {
|
||||
return this.queryBlobFromCache(USBBOOT_BOOTCODE_FILE_NAME, options.readFile).then((bootcode) => {
|
||||
return this.queryBlobFromCache(USBBOOT_BOOTCODE_FILE_NAME).then((bootcode) => {
|
||||
return USBBootAdapter.writeBootCode(device, endpoint, bootcode)
|
||||
})
|
||||
}
|
||||
@ -434,7 +429,6 @@ class USBBootAdapter extends EventEmitter {
|
||||
const STEPS_TOTAL = 38
|
||||
|
||||
return this.startFileServer(device, endpoint, {
|
||||
readFile: options.readFile,
|
||||
progress: (step) => {
|
||||
setProgress((step * (PERCENTAGE_TOTAL - PERCENTAGE_START) / STEPS_TOTAL) + PERCENTAGE_START)
|
||||
}
|
||||
@ -515,7 +509,6 @@ class USBBootAdapter extends EventEmitter {
|
||||
* @param {Object} device - node-usb device
|
||||
* @param {Object} endpoint - node-usb endpoint
|
||||
* @param {Object} options - options
|
||||
* @param {Function} options.readFile - read file function
|
||||
* @param {Function} options.progress - progress function (step)
|
||||
* @param {Number} [step] - current step (used internally)
|
||||
* @returns {Promise}
|
||||
@ -526,9 +519,6 @@ class USBBootAdapter extends EventEmitter {
|
||||
* const device = usb.findByIds(0x0a5c, 0x2763)
|
||||
*
|
||||
* adapter.startFileServer(device, device.interfaces(0).endpoint(1), {
|
||||
* readFile: (name) => {
|
||||
* return fs.readFileAsync(name)
|
||||
* },
|
||||
* progress: (step) => {
|
||||
* console.log(`Currently on step ${step}`)
|
||||
* }
|
||||
@ -568,7 +558,7 @@ class USBBootAdapter extends EventEmitter {
|
||||
if (fileMessage.command === protocol.FILE_MESSAGE_COMMANDS.GET_FILE_SIZE) {
|
||||
debug(`Getting the size of ${fileMessage.fileName}`)
|
||||
|
||||
return this.queryBlobFromCache(fileMessage.fileName, options.readFile).then((fileBuffer) => {
|
||||
return this.queryBlobFromCache(fileMessage.fileName).then((fileBuffer) => {
|
||||
const fileSize = fileBuffer.length
|
||||
debug(`Sending size: ${fileSize}`)
|
||||
return protocol.sendBufferSize(device, fileSize)
|
||||
@ -584,7 +574,7 @@ class USBBootAdapter extends EventEmitter {
|
||||
if (fileMessage.command === protocol.FILE_MESSAGE_COMMANDS.READ_FILE) {
|
||||
debug(`Reading ${fileMessage.fileName}`)
|
||||
|
||||
return this.queryBlobFromCache(fileMessage.fileName, options.readFile).then((fileBuffer) => {
|
||||
return this.queryBlobFromCache(fileMessage.fileName).then((fileBuffer) => {
|
||||
return protocol.write(device, endpoint, fileBuffer)
|
||||
}).catch({
|
||||
code: 'ENOENT'
|
||||
@ -613,5 +603,32 @@ class USBBootAdapter extends EventEmitter {
|
||||
*/
|
||||
USBBootAdapter.id = 'usbboot'
|
||||
|
||||
/**
|
||||
* @summary Read a usbboot blob
|
||||
* @private
|
||||
*
|
||||
* @param {String} filename - blob name
|
||||
* @fulfil {Buffer} - blob
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
* USBBootAdapter.readBlob('bootcode.bin')
|
||||
* .then((buffer) => { ... })
|
||||
* .catch((error) => { ... })
|
||||
*/
|
||||
USBBootAdapter.readBlob = (filename) => {
|
||||
const isRaspberryPi = _.includes([
|
||||
'bootcode.bin',
|
||||
'start_cd.elf',
|
||||
'fixup_cd.dat'
|
||||
], filename)
|
||||
|
||||
const blobPath = isRaspberryPi
|
||||
? path.join('raspberrypi', filename)
|
||||
: filename
|
||||
|
||||
return fs.readFileAsync(path.join(__dirname, 'blobs', blobPath))
|
||||
}
|
||||
|
||||
// Exports
|
||||
module.exports = USBBootAdapter
|
||||
|
Loading…
x
Reference in New Issue
Block a user