Merge pull request #2814 from balena-io/improve-scan-reliability

Improve discover balena os across different networks
This commit is contained in:
Otávio Jacobi 2024-07-17 04:42:50 -03:00 committed by GitHub
commit 245c51d974
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 21 deletions

View File

@ -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
View File

@ -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"
}