mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-04-09 04:14:15 +00:00
Improve discover balena os across different networks
This is an improvement over the scan, join and leave commands removing flakiness when searching over different networks. In short, instead of leaving bonjour to search across all interfaces, we forcebly conduct a search on each interface, this requires mDNS binding any ipv4 interface (0.0.0.0), otherwise it would bind over the interface itself, which is not desired as it causes services to only be able to receive information over that interface, see [mafintosh/multicast-dns#53](https://github.com/mafintosh/multicast-dns/issues/53). This targeted approach enhances the reliability and accuracy of network searches, reducing instances of missed connections or network errors typically caused by flakiness when relying on bonjour's default behavior. Change-type: patch
This commit is contained in:
parent
2c0c1f8fd1
commit
03f0f11f8b
@ -1,5 +1,6 @@
|
||||
import Bonjour from 'bonjour-service';
|
||||
import type { Service } from 'bonjour-service';
|
||||
import * as os from 'os';
|
||||
|
||||
interface LocalBalenaOsDevice {
|
||||
address: string;
|
||||
@ -19,20 +20,25 @@ const avahiBalenaSshSubtype = 'resin-device';
|
||||
export async function discoverLocalBalenaOsDevices(
|
||||
timeout = 4000,
|
||||
): Promise<LocalBalenaOsDevice[]> {
|
||||
const services = await new Promise<Service[]>((resolve) => {
|
||||
const bonjour = new Bonjour({}, async (err: string | Error) => {
|
||||
await (await import('../errors')).handleError(err);
|
||||
});
|
||||
const resinSshServices: Service[] = [];
|
||||
const browser = bonjour.find(avahiBalenaSshConfig, (service) =>
|
||||
resinSshServices.push(service),
|
||||
);
|
||||
setTimeout(() => {
|
||||
browser.stop();
|
||||
bonjour.destroy();
|
||||
resolve(resinSshServices);
|
||||
}, timeout);
|
||||
});
|
||||
// search over all network interfaces
|
||||
const networks = os.networkInterfaces();
|
||||
const validNics: os.NetworkInterfaceInfo[] = [];
|
||||
for (const networkName of Object.keys(networks)) {
|
||||
for (const iface of networks[networkName]!) {
|
||||
if (isIPv4(iface.family) && !iface.internal) {
|
||||
validNics.push(iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const allServices = await Promise.all(
|
||||
validNics.map((iface) => searchBalenaDevicesOnInterface(iface, timeout)),
|
||||
);
|
||||
|
||||
// dedupe services in case the same device is found on multiple interfaces
|
||||
const services = Array.from(
|
||||
new Map(allServices.flat().map((item) => [item.fqdn, item])).values(),
|
||||
);
|
||||
|
||||
return services
|
||||
.filter(
|
||||
@ -46,3 +52,36 @@ export async function discoverLocalBalenaOsDevices(
|
||||
port,
|
||||
}));
|
||||
}
|
||||
|
||||
async function searchBalenaDevicesOnInterface(
|
||||
iface: os.NetworkInterfaceInfo,
|
||||
timeout: number,
|
||||
): Promise<Service[]> {
|
||||
return await new Promise<Service[]>((resolve) => {
|
||||
const bonjour = new Bonjour(
|
||||
{
|
||||
// @ts-expect-error bonjour-service types are incorrect https://github.com/onlxltd/bonjour-service/issues/10
|
||||
interface: iface.address,
|
||||
// binds to receive from any incoming interface
|
||||
// see: https://github.com/mafintosh/multicast-dns/issues/53#issuecomment-638365104
|
||||
bind: '0.0.0.0',
|
||||
},
|
||||
async (err: string | Error) => {
|
||||
await (await import('../errors')).handleError(err);
|
||||
},
|
||||
);
|
||||
const resinSshServices: Service[] = [];
|
||||
const browser = bonjour.find(avahiBalenaSshConfig, (service) =>
|
||||
resinSshServices.push(service),
|
||||
);
|
||||
setTimeout(() => {
|
||||
browser.stop();
|
||||
bonjour.destroy();
|
||||
resolve(resinSshServices);
|
||||
}, timeout);
|
||||
});
|
||||
}
|
||||
|
||||
function isIPv4(family: string | number) {
|
||||
return family === 4 || family === 'IPv4';
|
||||
}
|
||||
|
13
npm-shrinkwrap.json
generated
13
npm-shrinkwrap.json
generated
@ -4257,9 +4257,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz",
|
||||
"integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==",
|
||||
"version": "20.14.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
|
||||
"integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
@ -5780,10 +5780,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/balena-sdk/node_modules/@types/node": {
|
||||
"version": "18.19.39",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz",
|
||||
"integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==",
|
||||
"license": "MIT",
|
||||
"version": "18.19.40",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.40.tgz",
|
||||
"integrity": "sha512-MIxieZHrm4Ee8XArBIc+Or9HINt2StOmCbgRcXGSJl8q14svRvkZPe7LJq9HKtTI1SK3wU8b91TjntUm7T69Pg==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user