Merge pull request #1464 from balena-io/1132-build-windows-docker-qemu

Fix 'balena build --emulated' on Windows (including default docker socket)
This commit is contained in:
Paulo Castro 2019-10-09 14:21:20 +01:00 committed by GitHub
commit 1987206b94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 116 additions and 50 deletions

View File

@ -1636,7 +1636,8 @@ Examples:
$ balena build ./source/ $ balena build ./source/
$ balena build --deviceType raspberrypi3 --arch armv7hf --emulated $ balena build --deviceType raspberrypi3 --arch armv7hf --emulated
$ balena build --application MyApp ./source/ $ balena build --application MyApp ./source/
$ balena build --docker '/var/run/docker.sock' $ balena build --docker /var/run/docker.sock # Linux, Mac
$ balena build --docker //./pipe/docker_engine # Windows
$ balena build --dockerHost my.docker.host --dockerPort 2376 --ca ca.pem --key key.pem --cert cert.pem $ balena build --dockerHost my.docker.host --dockerPort 2376 --ca ca.pem --key key.pem --cert cert.pem
### Options ### Options

View File

@ -75,7 +75,8 @@ module.exports =
$ balena build ./source/ $ balena build ./source/
$ balena build --deviceType raspberrypi3 --arch armv7hf --emulated $ balena build --deviceType raspberrypi3 --arch armv7hf --emulated
$ balena build --application MyApp ./source/ $ balena build --application MyApp ./source/
$ balena build --docker '/var/run/docker.sock' $ balena build --docker /var/run/docker.sock # Linux, Mac
$ balena build --docker //./pipe/docker_engine # Windows
$ balena build --dockerHost my.docker.host --dockerPort 2376 --ca ca.pem --key key.pem --cert cert.pem $ balena build --dockerHost my.docker.host --dockerPort 2376 --ca ca.pem --key key.pem --cert cert.pem
""" """
options: dockerUtils.appendOptions compose.appendOptions [ options: dockerUtils.appendOptions compose.appendOptions [

View File

@ -245,6 +245,7 @@ exports.buildProject = (
transpose.transposeTarStream task.buildStream, transpose.transposeTarStream task.buildStream,
hostQemuPath: toPosixPath(binPath) hostQemuPath: toPosixPath(binPath)
containerQemuPath: "/tmp/#{qemu.QEMU_BIN_NAME}" containerQemuPath: "/tmp/#{qemu.QEMU_BIN_NAME}"
qemuFileMode: 0o555
.then (stream) -> .then (stream) ->
task.buildStream = stream task.buildStream = stream
.return([ task, binPath ]) .return([ task, binPath ])

View File

@ -96,7 +96,6 @@ exports.appendOptions = (opts) ->
] ]
generateConnectOpts = (opts) -> generateConnectOpts = (opts) ->
buildDockerodeOpts = require('dockerode-options')
fs = require('mz/fs') fs = require('mz/fs')
_ = require('lodash') _ = require('lodash')
@ -114,12 +113,12 @@ generateConnectOpts = (opts) ->
else if opts.docker? and opts.dockerHost? else if opts.docker? and opts.dockerHost?
# Both provided, no obvious way to continue # Both provided, no obvious way to continue
throw new Error("Both a local docker socket and docker host have been provided. Don't know how to continue.") throw new Error("Both a local docker socket and docker host have been provided. Don't know how to continue.")
else if process.env.DOCKER_HOST
# If no explicit options are provided, use the env
connectOpts = buildDockerodeOpts(process.env.DOCKER_HOST)
else else
# No options anywhere, assume default docker local socket # Use docker-modem defaults which take the DOCKER_HOST env var into account
connectOpts.socketPath = '/var/run/docker.sock' # https://github.com/apocas/docker-modem/blob/v2.0.2/lib/modem.js#L16-L65
Modem = require('docker-modem')
defaultOpts = new Modem()
connectOpts[opt] = defaultOpts[opt] for opt in ['host', 'port', 'socketPath']
# Now need to check if the user wants to connect over TLS # Now need to check if the user wants to connect over TLS
# to the host # to the host
@ -194,7 +193,17 @@ getDockerToolbelt = _.once ->
# #
exports.createClient = createClient = (opts) -> exports.createClient = createClient = (opts) ->
Docker = getDockerToolbelt() Docker = getDockerToolbelt()
return new Docker(opts) docker = new Docker(opts)
modem = docker.modem
# Workaround for a docker-modem 2.0.x bug where it sets a default
# socketPath on Windows even if the input options specify a host/port.
if modem.socketPath and modem.host
if opts.socketPath
modem.host = undefined
modem.port = undefined
else if opts.host
modem.socketPath = undefined
return docker
ensureDockerSeemsAccessible = (docker) -> ensureDockerSeemsAccessible = (docker) ->
{ exitWithExpectedError } = require('./patterns') { exitWithExpectedError } = require('./patterns')

View File

@ -46,9 +46,9 @@ export async function installQemuIfNeeded(
/** /**
* Check whether the Docker daemon (including balenaEngine) requires explicit * Check whether the Docker daemon (including balenaEngine) requires explicit
* QEMU emulation setup. Note that Docker Desktop (Docker for Mac), and * QEMU emulation setup. Note that Docker Desktop (Windows and Mac), and also
* reportedly also Docker for Windows, have built-in support for binfmt_misc, * the older Docker for Mac, have built-in support for binfmt_misc, so they
* so they do not require explicity QEMU setup. References: * do not require explicit QEMU setup. References:
* - https://en.wikipedia.org/wiki/Binfmt_misc * - https://en.wikipedia.org/wiki/Binfmt_misc
* - https://docs.docker.com/docker-for-mac/multi-arch/ * - https://docs.docker.com/docker-for-mac/multi-arch/
* - https://www.ecliptik.com/Cross-Building-and-Running-Multi-Arch-Docker-Images/ * - https://www.ecliptik.com/Cross-Building-and-Running-Multi-Arch-Docker-Images/
@ -61,7 +61,7 @@ async function platformNeedsQemu(
logger: Logger, logger: Logger,
): Promise<boolean> { ): Promise<boolean> {
const dockerInfo = await docker.info(); const dockerInfo = await docker.info();
// Docker Desktop with Docker Engine 19.03 reports: // Docker Desktop (Windows and Mac) with Docker Engine 19.03 reports:
// OperatingSystem: Docker Desktop // OperatingSystem: Docker Desktop
// OSType: linux // OSType: linux
// Docker for Mac with Docker Engine 18.06 reports: // Docker for Mac with Docker Engine 18.06 reports:

122
npm-shrinkwrap.json generated
View File

@ -548,13 +548,6 @@
"integrity": "sha512-LLiivgWKii4JeMzFy3trrxqkRrVSdue8WmbXyHuSJLwNrhIQU5MTrc65jhxEPwMyh5HR1xevSdD+k2nnSRKw9g==", "integrity": "sha512-LLiivgWKii4JeMzFy3trrxqkRrVSdue8WmbXyHuSJLwNrhIQU5MTrc65jhxEPwMyh5HR1xevSdD+k2nnSRKw9g==",
"requires": { "requires": {
"@types/node": "*" "@types/node": "*"
},
"dependencies": {
"@types/node": {
"version": "12.0.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.10.tgz",
"integrity": "sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ=="
}
} }
}, },
"@types/events": { "@types/events": {
@ -4034,14 +4027,15 @@
"integrity": "sha512-djh3R7KXkEPm80PXK9xbz8bCfEFuU11Tmf5l9IXKdjBPx91/cOqhwOwtOq6s35B8TqrwY6L4xLphmyYmJT0ZXw==" "integrity": "sha512-djh3R7KXkEPm80PXK9xbz8bCfEFuU11Tmf5l9IXKdjBPx91/cOqhwOwtOq6s35B8TqrwY6L4xLphmyYmJT0ZXw=="
}, },
"docker-modem": { "docker-modem": {
"version": "1.0.9", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-1.0.9.tgz", "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-2.0.2.tgz",
"integrity": "sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw==", "integrity": "sha512-Aq6NBJQm5najFlg4wRZtSrWXzQbQClh1kccAkUWIdVhuyHK6tYhmi9W9xtVaGmzBa0Nfuwi4AEbQzWtHZT+2Jw==",
"requires": { "requires": {
"JSONStream": "1.3.2", "JSONStream": "1.3.2",
"debug": "^3.2.6", "debug": "^3.2.6",
"readable-stream": "~1.0.26-4", "readable-stream": "~1.0.26-4",
"split-ca": "^1.0.0" "split-ca": "^1.0.0",
"ssh2": "^0.8.5"
}, },
"dependencies": { "dependencies": {
"JSONStream": { "JSONStream": {
@ -4077,6 +4071,24 @@
"string_decoder": "~0.10.x" "string_decoder": "~0.10.x"
} }
}, },
"ssh2": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.8.5.tgz",
"integrity": "sha512-TkvzxSYYUSQ8jb//HbHnJVui4fVEW7yu/zwBxwro/QaK2EGYtwB+8gdEChwHHuj142c5+250poMC74aJiwApPw==",
"requires": {
"ssh2-streams": "~0.4.4"
}
},
"ssh2-streams": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.6.tgz",
"integrity": "sha512-jXq/nk2K82HuueO9CTCdas/a0ncX3fvYzEPKt1+ftKwE5RXTX25GyjcpjBh2lwVUYbk0c9yq6cBczZssWmU3Tw==",
"requires": {
"asn1": "~0.2.0",
"bcrypt-pbkdf": "^1.0.2",
"streamsearch": "~0.1.2"
}
},
"string_decoder": { "string_decoder": {
"version": "0.10.31", "version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
@ -4099,9 +4111,9 @@
} }
}, },
"docker-qemu-transpose": { "docker-qemu-transpose": {
"version": "0.5.3", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/docker-qemu-transpose/-/docker-qemu-transpose-0.5.3.tgz", "resolved": "https://registry.npmjs.org/docker-qemu-transpose/-/docker-qemu-transpose-1.0.1.tgz",
"integrity": "sha512-SAFOPwZSk3kruvEGyCafhjeidggIf42x2u3oSTV/id/hT/jtl8vXw5o6RGpPEQIraUtCyiQ0Vw2NFzGJqvFvVA==", "integrity": "sha512-qTNis+0NUBYhxdigLu6gT9bxMnck0NOd6gc8ci6n3yfSZPiIjtsuWeci3Os0P+GJw8tH08I0pckrtrD/MZ/0Rw==",
"requires": { "requires": {
"@types/bluebird": "^3.5.2", "@types/bluebird": "^3.5.2",
"@types/event-stream": "^3.3.31", "@types/event-stream": "^3.3.31",
@ -4114,18 +4126,14 @@
"jsesc": "^2.5.0", "jsesc": "^2.5.0",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"stream-to-promise": "^2.2.0", "stream-to-promise": "^2.2.0",
"tar-stream": "^1.5.2" "tar-stream": "^1.5.2",
"tar-utils": "^2.0.0"
}, },
"dependencies": { "dependencies": {
"@types/lodash": {
"version": "4.14.135",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.135.tgz",
"integrity": "sha512-Ed+tSZ9qM1oYpi5kzdsBuOzcAIn1wDW+e8TFJ50IMJMlSopGdJgKAbhHzN6h1E1OfjlGOr2JepzEWtg9NIfoNg=="
},
"@types/node": { "@types/node": {
"version": "7.10.6", "version": "7.10.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.10.6.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-7.10.7.tgz",
"integrity": "sha512-d0BOAicT0tEdbdVQlLGOVul1kvg6YvbaADRCThGCz5NJ0e9r00SofcR1x69hmlCyrHuB6jd4cKzL9bMLjPnpAA==" "integrity": "sha512-4I7+hXKyq7e1deuzX9udu0hPIYqSSkdKXtjow6fMnQ3OR9qkxIErGHbGY08YrfZJrCS1ajK8lOuzd0k3n2WM4A=="
} }
} }
}, },
@ -4229,13 +4237,59 @@
"concat-stream": "~1.6.2", "concat-stream": "~1.6.2",
"docker-modem": "^1.0.8", "docker-modem": "^1.0.8",
"tar-fs": "~1.16.3" "tar-fs": "~1.16.3"
},
"dependencies": {
"JSONStream": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz",
"integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=",
"requires": {
"jsonparse": "^1.2.0",
"through": ">=2.2.7 <3"
}
},
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"requires": {
"ms": "^2.1.1"
}
},
"docker-modem": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-1.0.9.tgz",
"integrity": "sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw==",
"requires": {
"JSONStream": "1.3.2",
"debug": "^3.2.6",
"readable-stream": "~1.0.26-4",
"split-ca": "^1.0.0"
}
},
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"readable-stream": {
"version": "1.0.34",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
}
} }
}, },
"dockerode-options": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/dockerode-options/-/dockerode-options-0.2.1.tgz",
"integrity": "sha1-E3y4CeznrFta1StffhzXmPOj0LQ="
},
"dom-serializer": { "dom-serializer": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
@ -5473,9 +5527,9 @@
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
}, },
"fp-ts": { "fp-ts": {
"version": "2.0.5", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.0.5.tgz", "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.1.0.tgz",
"integrity": "sha512-opI5r+rVlpZE7Rhk0YtqsrmxGkbIw0dRNqGca8FEAMMnjomXotG+R9QkLQg20onx7R8qhepAn4CCOP8usma/Xw==" "integrity": "sha512-2xTHhLuP0uLjpaHAARpGQ1TpIPqEUMu8fGN5jv8py0T+HgB6a4bV57p5EQoOyeHws4SuYxiUi2/m0isHs6F/cA=="
}, },
"fragment-cache": { "fragment-cache": {
"version": "0.2.1", "version": "0.2.1",
@ -15351,9 +15405,9 @@
} }
}, },
"resin-multibuild": { "resin-multibuild": {
"version": "4.3.1", "version": "4.3.2",
"resolved": "https://registry.npmjs.org/resin-multibuild/-/resin-multibuild-4.3.1.tgz", "resolved": "https://registry.npmjs.org/resin-multibuild/-/resin-multibuild-4.3.2.tgz",
"integrity": "sha512-tpocIxmIRvMGMMUF5wCjy0DcZS2jIzKZ65CtMoIxMcV9Pp25JjhDyUqIVEpC1RO6I/C+pHqWfhSyLiYj9B+rYg==", "integrity": "sha512-ZBMT9AJ6IMkXW6VkQB4ZdNTB8TCpJjiroLleJ/Gmskgjzo/tVbMJPWimpYcpr8JrFfXPn8wt4bGuoVy59CzefA==",
"requires": { "requires": {
"@types/bluebird": "3.5.20", "@types/bluebird": "3.5.20",
"@types/dockerode": "2.5.5", "@types/dockerode": "2.5.5",

View File

@ -169,10 +169,10 @@
"common-tags": "^1.7.2", "common-tags": "^1.7.2",
"denymount": "^2.3.0", "denymount": "^2.3.0",
"docker-progress": "^4.0.0", "docker-progress": "^4.0.0",
"docker-qemu-transpose": "^0.5.3", "docker-qemu-transpose": "^1.0.1",
"docker-modem": "^2.0.2",
"docker-toolbelt": "^3.3.7", "docker-toolbelt": "^3.3.7",
"dockerode": "^2.5.8", "dockerode": "^2.5.8",
"dockerode-options": "^0.2.1",
"ejs": "^2.5.7", "ejs": "^2.5.7",
"etcher-sdk": "^2.0.14", "etcher-sdk": "^2.0.14",
"event-stream": "3.3.4", "event-stream": "3.3.4",
@ -208,7 +208,7 @@
"resin-compose-parse": "^2.1.0", "resin-compose-parse": "^2.1.0",
"resin-doodles": "0.0.1", "resin-doodles": "0.0.1",
"resin-image-fs": "^5.0.8", "resin-image-fs": "^5.0.8",
"resin-multibuild": "^4.3.1", "resin-multibuild": "^4.3.2",
"resin-release": "^1.2.0", "resin-release": "^1.2.0",
"resin-semver": "^1.6.0", "resin-semver": "^1.6.0",
"resin-stream-logger": "^0.1.2", "resin-stream-logger": "^0.1.2",