I was wondering if there is a way to flash multiple devices all at once using balena-cli, just like with balena etcher. I’m trying to create a system that can automate the flashing of multiple raspberry pi compute modules, which is why I chose to implement balena-cli.
My colleagues from the Etcher team just shared a potential way to do multi-write using the Etcher sdk.
Please, do try these steps with the etcher-sdk directly:
git clone https://github.com/balena-io-modules/etcher-sdk
cd etcher-sdk
npm install \# assumes node is already installed on the computer
npm i -g ts-node
ts-node examples/multi-destination.ts input.img /dev/sda,/dev/sdb,/dev/sdx
# ts-node examples/multi-destination.ts --help is also useful
On the other hand, my colleagues shared that the balena CLI doesn’t enable more than one target as you demonstrated, and probably this is a good feature request. Feel free to add it on the github repo here if it doesn’t exist.
Thank you for sharing. I wasn’t feeling well for the past few days, so I was only able to try it now. I seem to have a problem on npm install. This is the error that I got when running the command
npm WARN deprecated coffee-script@1.11.1: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
npm WARN deprecated tslint@6.1.3: TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.
npm ERR! code 1
npm ERR! path /home/pi/etcher-sdk/node_modules/usb
npm ERR! command failed
npm ERR! command sh -c node-gyp-build
npm ERR! make: Entering directory '/home/pi/etcher-sdk/node_modules/usb/build'
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/core.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/descriptor.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/hotplug.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/io.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/strerror.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/sync.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/os/poll_posix.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/os/threads_posix.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/os/linux_usbfs.o
npm ERR! CC(target) Release/obj.target/libusb/libusb/libusb/os/linux_udev.o
npm ERR! make: Leaving directory '/home/pi/etcher-sdk/node_modules/usb/build'
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@7.1.2
npm ERR! gyp info using node@12.22.12 | linux | arm64
npm ERR! gyp info find Python using Python version 3.9.2 found at "/usr/bin/python3"
npm ERR! gyp info spawn /usr/bin/python3
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args '/usr/share/nodejs/node-gyp/gyp/gyp_main.py',
npm ERR! gyp info spawn args 'binding.gyp',
npm ERR! gyp info spawn args '-f',
npm ERR! gyp info spawn args 'make',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/home/pi/etcher-sdk/node_modules/usb/build/config.gypi',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/usr/share/nodejs/node-gyp/addon.gypi',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/usr/include/nodejs/common.gypi',
npm ERR! gyp info spawn args '-Dlibrary=shared_library',
npm ERR! gyp info spawn args '-Dvisibility=default',
npm ERR! gyp info spawn args '-Dnode_root_dir=/usr/include/nodejs',
npm ERR! gyp info spawn args '-Dnode_gyp_dir=/usr/share/nodejs/node-gyp',
npm ERR! gyp info spawn args '-Dnode_lib_file=/usr/include/nodejs/<(target_arch)/node.lib',
npm ERR! gyp info spawn args '-Dmodule_root_dir=/home/pi/etcher-sdk/node_modules/usb',
npm ERR! gyp info spawn args '-Dnode_engine=v8',
npm ERR! gyp info spawn args '--depth=.',
npm ERR! gyp info spawn args '--no-parallel',
npm ERR! gyp info spawn args '--generator-output',
npm ERR! gyp info spawn args 'build',
npm ERR! gyp info spawn args '-Goutput_dir=.'
npm ERR! gyp info spawn args ]
npm ERR! gyp info spawn make
npm ERR! gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
npm ERR! ../libusb/libusb/os/linux_udev.c:40:10: fatal error: libudev.h: No such file or directory
npm ERR! 40 | #include <libudev.h>
npm ERR! | ^~~~~~~~~~~
npm ERR! compilation terminated.
npm ERR! make: *** [libusb.target.mk:152: Release/obj.target/libusb/libusb/libusb/os/linux_udev.o] Error 1
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: `make` failed with exit code: 2
npm ERR! gyp ERR! stack at ChildProcess.onExit (/usr/share/nodejs/node-gyp/lib/build.js:194:23)
npm ERR! gyp ERR! stack at ChildProcess.emit (events.js:314:20)
npm ERR! gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:276:12)
npm ERR! gyp ERR! System Linux 5.15.56-v8+
npm ERR! gyp ERR! command "/usr/bin/node" "/usr/share/nodejs/node-gyp/bin/node-gyp.js" "rebuild"
npm ERR! gyp ERR! cwd /home/pi/etcher-sdk/node_modules/usb
npm ERR! gyp ERR! node -v v12.22.12
npm ERR! gyp ERR! node-gyp -v v7.1.2
npm ERR! gyp ERR! not ok
npm ERR! A complete log of this run can be found in:
npm ERR! /home/pi/.npm/_logs/2022-08-25T10_20_11_655Z-debug.log
native modules are never easy and the sdk has many of them.
From the error it looks like libusb or libudev is missing.
you may run sudo apt-get install libusb-1.0-0-dev
and/or sudo apt-get install libudev-dev
the command may be different depending on your package manager and available repositories.
Then you can try npm install again.
Let us know if it has any other issues.
> etcher-sdk@7.2.0 prepublish
> npm run build
> etcher-sdk@7.2.0 build
> tsc
lib/lazy.ts:26:63 - error TS2307: Cannot find module 'node-raspberrypi-usbboot' or its corresponding type declarations.
26 return require('node-raspberrypi-usbboot') as typeof import('node-raspberrypi-usbboot');
~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/scanner/adapters/usbboot.ts:20:8 - error TS2307: Cannot find module 'node-raspberrypi-usbboot' or its corresponding type declarations.
20 } from 'node-raspberrypi-usbboot';
~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/source-destination/usbboot.ts:17:31 - error TS2307: Cannot find module 'node-raspberrypi-usbboot' or its corresponding type declarations.
17 import { UsbbootDevice } from 'node-raspberrypi-usbboot';
~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/source-destination/usbboot.ts:42:29 - error TS7006: Parameter 'value' implicitly has an 'any' type.
42 usbDevice.on('progress', (value) => {
~~~~~
Found 4 errors in 3 files.
Errors Files
1 lib/lazy.ts:26
1 lib/scanner/adapters/usbboot.ts:20
2 lib/source-destination/usbboot.ts:17
npm ERR! code 2
npm ERR! path /home/pi/etcher-sdk
npm ERR! command failed
npm ERR! command sh -c tsc
npm ERR! A complete log of this run can be found in:
npm ERR! /home/pi/.npm/_logs/2022-08-25T12_21_07_616Z-debug.log
npm ERR! code 2
npm ERR! path /home/pi/etcher-sdk
npm ERR! command failed
npm ERR! command sh -c npm run build
npm ERR! A complete log of this run can be found in:
npm ERR! /home/pi/.npm/_logs/2022-08-25T12_21_07_671Z-debug.log
Almost,
it is referring to balena-io-modules/node-raspberrypi-usbboot (github.com).
It is listed in the package.json, so npm install should have pulled it too.
You may try a clean new clone and npm install.
Or add skipLibCheck: true and noImplicitAny: false to your tsconfig.json
I tried both options and I still get the same error message (‘node-raspberry-pi’ module not found). Here is the current stand of tsconfig.json with all the recommended changes
I beleive skipLibCheck: true also belongs in the "compilerOptions" object. Sorry for the unprecise instructions before.
By the way I had the project on my machine, and I cloned it again to double check and for me it works fine, it is really strange that you have this error.
To narrow down the possible causes, can you tell which version of node/npm you have?
I tried it on a separate setup using node v18 and I was able to install ts-node. I’d have to wait for next week to try writing an image to multiple compute modules, but I’m happy to have it up and running
I tried flashing an sd-card using ts-node on the raspberry pi and I got a runtime error. Here’s what it says:
RuntimeError: abort(TypeError: Failed to parse URL from /home/pi/etcher-sdk/node_modules/ext2fs/lib/libext2fs.wasm). Build with -s ASSERTIONS=1 for more info.
at process.abort (/home/pi/etcher-sdk/node_modules/ext2fs/lib/libext2fs.js:1:11250)
at process.emit (node:events:525:35)
at process.emit (node:domain:489:12)
at process.emit.sharedData.processEmitHook.installedValue [as emit] (/home/pi/.nvm/versions/node/v18.9.0/lib/node_modules/ts-node/node_modules/@cspotcode/source-map-support/source-map-support.js:745:40)
at emit (node:internal/process/promises:149:20)
at processPromiseRejections (node:internal/process/promises:283:27)
at processTicksAndRejections (node:internal/process/task_queues:96:32)
Node.js v18.9.0
I tried installing the libext2fs package, but that didn’t seem to remediate it