diff --git a/lib/modem.js b/lib/modem.js index ecf591f..9062eb7 100644 --- a/lib/modem.js +++ b/lib/modem.js @@ -9,7 +9,8 @@ var querystring = require('querystring'), utils = require('./utils'), util = require('util'), splitca = require('split-ca'), - isWin = require('os').type() === 'Windows_NT', + os = require('os'), + isWin = os.type() === 'Windows_NT', stream = require('stream'); var defaultOpts = function () { @@ -18,12 +19,12 @@ var defaultOpts = function () { if (!process.env.DOCKER_HOST) { // Windows socket path: //./pipe/docker_engine ( Windows 10 ) - // Linux & Darwin socket path: /var/run/docker.sock - opts.socketPath = isWin ? '//./pipe/docker_engine' : '/var/run/docker.sock'; + // Linux & Darwin socket path is /var/run/docker.sock when running system-wide, + // or $HOME/.docker/run/docker.sock in new Docker Desktop installs. + opts.socketPath = isWin ? '//./pipe/docker_engine' : findDefaultUnixSocket; } else if (process.env.DOCKER_HOST.indexOf('unix://') === 0) { - // Strip off unix://, fall back to default of /var/run/docker.sock if - // unix:// was passed without a path - opts.socketPath = process.env.DOCKER_HOST.substring(7) || '/var/run/docker.sock'; + // Strip off unix://, fall back to default if unix:// was passed without a path + opts.socketPath = process.env.DOCKER_HOST.substring(7) || findDefaultUnixSocket; } else if (process.env.DOCKER_HOST.indexOf('npipe://') === 0) { // Strip off npipe://, fall back to default of //./pipe/docker_engine if // npipe:// was passed without a path @@ -76,6 +77,16 @@ var defaultOpts = function () { return opts; }; +var findDefaultUnixSocket = function () { + return new Promise(function (resolve) { + var userDockerSocket = path.join(os.homedir(), '.docker', 'run', 'docker.sock'); + fs.access(userDockerSocket, function (err) { + if (err) resolve('/var/run/docker.sock'); + else resolve(userDockerSocket); + }) + }); +} + var Modem = function (options) { var optDefaults = defaultOpts(); @@ -220,17 +231,30 @@ Modem.prototype.dial = function (options, callback) { } if (this.socketPath) { - optionsf.socketPath = this.socketPath; + // SocketPath may be a function that can return a promise: + this.getSocketPath().then((socketPath) => { + optionsf.socketPath = socketPath; + this.buildRequest(optionsf, options, data, callback); + }); } else { var urlp = url.parse(address); optionsf.hostname = urlp.hostname; optionsf.port = urlp.port; optionsf.path = urlp.path; - } - this.buildRequest(optionsf, options, data, callback); + this.buildRequest(optionsf, options, data, callback); + } }; +Modem.prototype.getSocketPath = function () { + if (!this.socketPath) return; + + var socketPathValue = typeof this.socketPath === 'function' + ? this.socketPath() : this.socketPath; + + return Promise.resolve(socketPathValue); +} + Modem.prototype.buildRequest = function (options, context, data, callback) { var self = this; var connectionTimeoutTimer; diff --git a/test/modem_test.js b/test/modem_test.js index 57e1855..d12e5a4 100644 --- a/test/modem_test.js +++ b/test/modem_test.js @@ -1,7 +1,11 @@ var assert = require('assert'); +var path = require('path'); +var os = require('os'); var http = require('http'); var Modem = require('../lib/modem'); -var defaultSocketPath = require('os').type() === 'Windows_NT' ? '//./pipe/docker_engine' : '/var/run/docker.sock'; + +var unixDefaultSocketPaths = ['/var/run/docker.sock', path.join(os.homedir(), '.docker/run/docker.sock')] +var defaultSocketPaths = os.type() === 'Windows_NT' ? ['//./pipe/docker_engine'] : unixDefaultSocketPaths; describe('Modem', function () { beforeEach(function () { @@ -10,8 +14,11 @@ describe('Modem', function () { it('should default to default socket path', function () { var modem = new Modem(); - assert.ok(modem.socketPath); - assert.strictEqual(modem.socketPath, defaultSocketPath); + + return modem.getSocketPath().then((socketPath) => { + assert.ok(socketPath); + assert.ok(defaultSocketPaths.includes(socketPath)); + }); }); it('should use specific cert, key and ca', function () { @@ -50,9 +57,12 @@ describe('Modem', function () { headers: customHeaders }); assert.ok(modem.headers); - assert.ok(modem.socketPath); - assert.strictEqual(modem.socketPath, defaultSocketPath); assert.strictEqual(modem.headers, customHeaders); + + return modem.getSocketPath().then((socketPath) => { + assert.ok(socketPath); + assert.ok(defaultSocketPaths.includes(socketPath)); + }); }); it('should allow DOCKER_HOST=unix:///path/to/docker.sock', function () { @@ -67,8 +77,10 @@ describe('Modem', function () { process.env.DOCKER_HOST = 'unix://'; var modem = new Modem(); - assert.ok(modem.socketPath); - assert.strictEqual(modem.socketPath, '/var/run/docker.sock'); + return modem.getSocketPath().then((socketPath) => { + assert.ok(socketPath); + assert.ok(unixDefaultSocketPaths.includes(socketPath)); + }); }); it('should interpret DOCKER_HOST=tcp://N.N.N.N:2376 as https', function () {