mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-02-21 09:51:58 +00:00
Introduce workaround that fixes windows dns issue on balena push
using .local device names.
Improve error handling in deployToDevice so that versionErrors don't mask other errors. Resolves:#1518 Change-type:patch Signed-off-by:Scott Lowe <scott@balena.io>
This commit is contained in:
parent
622c510d65
commit
53325b7c05
@ -30,9 +30,11 @@ import { Readable } from 'stream';
|
|||||||
|
|
||||||
import { BALENA_ENGINE_TMP_PATH } from '../../config';
|
import { BALENA_ENGINE_TMP_PATH } from '../../config';
|
||||||
import { checkBuildSecretsRequirements, makeBuildTasks } from '../compose_ts';
|
import { checkBuildSecretsRequirements, makeBuildTasks } from '../compose_ts';
|
||||||
|
import { workaroundWindowsDnsIssue } from '../helpers';
|
||||||
import Logger = require('../logger');
|
import Logger = require('../logger');
|
||||||
import { DeviceAPI, DeviceInfo } from './api';
|
import { DeviceAPI, DeviceInfo } from './api';
|
||||||
import * as LocalPushErrors from './errors';
|
import * as LocalPushErrors from './errors';
|
||||||
|
import { DeviceAPIError } from './errors';
|
||||||
import LivepushManager from './live';
|
import LivepushManager from './live';
|
||||||
import { displayBuildLog } from './logs';
|
import { displayBuildLog } from './logs';
|
||||||
|
|
||||||
@ -74,7 +76,7 @@ async function environmentFromInput(
|
|||||||
const varRegex = /^(?:([^\s:]+):)?([^\s]+?)=(.*)$/;
|
const varRegex = /^(?:([^\s:]+):)?([^\s]+?)=(.*)$/;
|
||||||
|
|
||||||
const ret: ParsedEnvironment = {};
|
const ret: ParsedEnvironment = {};
|
||||||
// Propolulate the object with the servicenames, as it
|
// Populate the object with the servicenames, as it
|
||||||
// also means that we can do a fast lookup of whether a
|
// also means that we can do a fast lookup of whether a
|
||||||
// service exists
|
// service exists
|
||||||
for (const service of serviceNames) {
|
for (const service of serviceNames) {
|
||||||
@ -139,6 +141,8 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await workaroundWindowsDnsIssue(opts.deviceHost);
|
||||||
|
|
||||||
const versionError = new Error(
|
const versionError = new Error(
|
||||||
'The supervisor version on this remote device does not support multicontainer local mode. ' +
|
'The supervisor version on this remote device does not support multicontainer local mode. ' +
|
||||||
'Please update your device to balenaOS v2.20.0 or greater from the dashboard.',
|
'Please update your device to balenaOS v2.20.0 or greater from the dashboard.',
|
||||||
@ -156,10 +160,18 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
|
|||||||
);
|
);
|
||||||
opts.nolive = true;
|
opts.nolive = true;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (e) {
|
||||||
exitWithExpectedError(versionError);
|
// Very old supervisor versions do not support /version endpoint
|
||||||
|
// a DeviceAPIError is expected in this case
|
||||||
|
if (e instanceof DeviceAPIError) {
|
||||||
|
exitWithExpectedError(versionError);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await workaroundWindowsDnsIssue(opts.deviceHost);
|
||||||
|
|
||||||
globalLogger.logInfo(`Starting build on device ${opts.deviceHost}`);
|
globalLogger.logInfo(`Starting build on device ${opts.deviceHost}`);
|
||||||
|
|
||||||
const project = await loadProject(
|
const project = await loadProject(
|
||||||
@ -183,6 +195,8 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
|
|||||||
// Try to detect the device information
|
// Try to detect the device information
|
||||||
const deviceInfo = await api.getDeviceInformation();
|
const deviceInfo = await api.getDeviceInformation();
|
||||||
|
|
||||||
|
await workaroundWindowsDnsIssue(opts.deviceHost);
|
||||||
|
|
||||||
let buildLogs: Dictionary<string> | undefined;
|
let buildLogs: Dictionary<string> | undefined;
|
||||||
if (!opts.nolive) {
|
if (!opts.nolive) {
|
||||||
buildLogs = {};
|
buildLogs = {};
|
||||||
@ -218,6 +232,8 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
|
|||||||
|
|
||||||
await api.setTargetState(targetState);
|
await api.setTargetState(targetState);
|
||||||
|
|
||||||
|
await workaroundWindowsDnsIssue(opts.deviceHost);
|
||||||
|
|
||||||
// Now that we've set the target state, the device will do it's thing
|
// Now that we've set the target state, the device will do it's thing
|
||||||
// so we can either just display the logs, or start a livepush session
|
// so we can either just display the logs, or start a livepush session
|
||||||
// (whilst also display logs)
|
// (whilst also display logs)
|
||||||
|
@ -338,3 +338,21 @@ function windowsCmdExeEscapeArg(arg: string): string {
|
|||||||
// duplicate internal double quotes, and double quote overall
|
// duplicate internal double quotes, and double quote overall
|
||||||
return `"${arg.replace(/["]/g, '""')}"`;
|
return `"${arg.replace(/["]/g, '""')}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Workaround a window system bug which causes multiple rapid DNS lookups
|
||||||
|
* to fail for mDNS.
|
||||||
|
*
|
||||||
|
* It introduces a simple pause, and should be used between operations that
|
||||||
|
* trigger mDNS resolutions.
|
||||||
|
*
|
||||||
|
* Windows bug: https://support.microsoft.com/en-gb/help/4057932/getaddrinfo-failed-with-wsahost-not-found-11001-error
|
||||||
|
*/
|
||||||
|
export async function workaroundWindowsDnsIssue(ipOrHostname: string) {
|
||||||
|
// 300ms seemed to be the smallest delay that worked reliably but may
|
||||||
|
// vary between systems.
|
||||||
|
const delay = 500;
|
||||||
|
if (process.platform === 'win32' && ipOrHostname.includes('.local')) {
|
||||||
|
await new Promise(r => setTimeout(r, delay));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user