Skip to content

Commit

Permalink
docker-file-sharing-fixed (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
SquatsTonight committed Aug 22, 2019
1 parent e2f7870 commit 04def63
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 5 deletions.
15 changes: 15 additions & 0 deletions docs/usage/faq-zh.md
Expand Up @@ -84,6 +84,8 @@ Resources:

本地使用 Fun 时,如果需要在本地运行、调试函数,则需要使用 fun local 子命令。使用 fun local 子命令就需要预先安装 Docker。

#### Windows

如果在您的 Windows 系统上安装的是 Docker Toolbox,在本地使用 `fun local invoke` 或者 `fun local start` 命令时提示信息如下:<br />![image.png](/figures/fun_local_error_on_toolbox.png)

提示默认主机路径为 C:\Users,Docker Toolbox 只能挂载 C 盘当前用户的目录,挂载其它盘都不会生效。错误信息中路径为 `D:\image_crawler`,所以失败。<br />如果想挂载其它盘符的路径,步骤如下:<br />1.打开 `Oracle VM VirtualBox`
Expand All @@ -97,3 +99,16 @@ Resources:
****: step 5 中的**共享文件夹名称**应按照上述格式手动填写。盘符小写,且以 `/` 为分隔符,同时保证路径完整性。例如:`d/fun/demo``e/fun/work` ...

由于 `Docker Toolbox` 官方也已经不在维护,为了更好的体验,我们希望您使用 [Docker For Windows](http://mirrors.aliyun.com/docker-toolbox/windows/docker-for-windows/beta/)。(建议使用我们提供的安装链接,某些版本的 Docker for Windows 可能存在不稳定的问题。)

#### MacOS
如果在您的 MacOS 系统上安装了 Docker,在本地使用在本地使用 `fun local invoke` 或者 `fun local start` 命令时提示信息如下:<br />![image.png](/figures/fun_local_error_on_docker_share_file.png)

提示添加相应路径至 Docker File sharing list , 这是因为您的 CodeUri 对应的目录不在 Docker 的 File Sharing 中,需要手动添加,步骤如下:<br />1.打开 `Docker Preferences`

![image.png](/figures/docker-preferences.png)

2.选择共享文件夹,选择`File Sharing`,点击`+`,选择 CodeUri 对应的目录,添加后点击`Apply & Restart`

![image.png](/figures/add_docker_file_sharing.png)

****:更多信息请参考 [Docker For Mac](https://docs.docker.com/docker-for-mac/osxfs/)
Binary file added figures/add_docker_file_sharing.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/docker-preferences.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/fun_local_error_on_docker_share_file.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions lib/docker-support.js
@@ -0,0 +1,46 @@
'use strict';
const fs = require('fs-extra');
const path = require('path');
const USER_HOME = require('os').homedir();
const defaultFileSharingPaths = [
'/Users',
'/Volumes',
'/private',
'/tmp'
];

async function getSharedPathsOfDockerForMac() {

const settingsPath = path.join(USER_HOME, 'Library/Group Containers/group.com.docker/settings.json');

const fileData = await fs.readFile(settingsPath, 'utf8');

const settings = JSON.parse(fileData);

if (settings.hasOwnProperty('defaultFileSharingPaths')) {
return settings.defaultFileSharingPaths;
}
return defaultFileSharingPaths;
}

async function findPathsOutofSharedPaths(mounts) {

const dockerSharedPaths = await getSharedPathsOfDockerForMac();
let pathsOutofSharedPaths = [];
for (let mount of mounts) {
const mountPath = mount.Source;
let isMountPathSharedToDocker = false;
for (let dockerSharedPath of dockerSharedPaths) {
if (mountPath.startsWith(dockerSharedPath)) {
isMountPathSharedToDocker = true;
break;
}
}
if (!isMountPathSharedToDocker) {
pathsOutofSharedPaths.push(mountPath);
}
}
return pathsOutofSharedPaths;
}

module.exports = { findPathsOutofSharedPaths };
19 changes: 16 additions & 3 deletions lib/docker.js
Expand Up @@ -14,7 +14,7 @@ const getVisitor = require('./visitor').getVisitor;
const definition = require('./definition');
const nas = require('./nas');
const { addEnv, addInstallTargetEnv, resolveLibPathsFromLdConf } = require('./install/env');

const { findPathsOutofSharedPaths } = require('./docker-support');
const detectTplPath = require('./tpl').detectTplPath;
const _ = require('lodash');

Expand Down Expand Up @@ -470,6 +470,17 @@ function resolveDockerUser(nasConfig) {
}

async function createContainer(opts) {
const isWin = process.platform === 'win32';
const isMac = process.platform === 'darwin';

if (opts && isMac) {
if (opts.HostConfig) {
const pathsOutofSharedPaths = await findPathsOutofSharedPaths(opts.HostConfig.Mounts);
if (isMac && pathsOutofSharedPaths.length > 0) {
throw new Error(red(`Please add ${pathsOutofSharedPaths} to Docker File sharing list, more information please refer to https://github.com/alibaba/funcraft/blob/master/docs/usage/faq-zh.md`));
}
}
}

let container;
try {
Expand All @@ -478,11 +489,13 @@ async function createContainer(opts) {
} catch (ex) {

if (ex.message.indexOf('invalid mount config for type') !== -1 && await isDockerToolBox()) {

throw new Error(red(`The default host machine path for docker toolbox is under 'C:\\Users', Please make sure your project is in this directory. If you want to mount other disk paths, please refer to https://github.com/alibaba/funcraft/blob/master/docs/usage/faq-zh.md .`));
}
if (ex.message.indexOf('drive is not shared') !== -1 && isWin) {
throw new Error(red(`${ex.message}More information please refer to https://docs.docker.com/docker-for-windows/#shared-drives`));
}
throw ex;
}
}
return container;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/nas/path.js
Expand Up @@ -11,7 +11,7 @@ const { red } = require('colors');
// Windows 下 process.env.HOME、process.env.USERPROFILE 均返回用户 home 目录
// macOS 下 process.env.HOME 返回用户 home 目录,process.env.USERPROFILE 和 process.env.HOMEPATH均返回 undefined
// 其他系统未知,这样写可以覆盖到不同操作系统的情况
const USER_HOME = process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH;
const USER_HOME = require('os').homedir();
// 正常 nasUri 示例 : nas://$(serviceName)$(mountDir) 或者 nas://$(serviceName):$(mountDir)
// 当 template.yml 中只存在单个服务时,上述 $(serviceName) 可以省略不写
const NAS_URI_PATTERN = /^nas:\/\/([^/:]*):?((?:\/[^/]+)*\/?)$/;
Expand Down
35 changes: 35 additions & 0 deletions test/docker-support.test.js
@@ -0,0 +1,35 @@
'use strict';

const expect = require('expect.js');
const sinon = require('sinon');
const sandbox = sinon.createSandbox();
const dockerSupport = require('../lib/docker-support');
const fs = require('fs-extra');

describe('test getMountPathsNotSharedToDocker', () => {
let readFile;
beforeEach(() => {
readFile = sandbox.stub(fs, 'readFile');
});
afterEach(() => {
sandbox.restore();
});

it('mount paths all shared to docker', async () => {
readFile.returns('{}');
const mounts = [{'Source': '/Users/test'}, {'Source': '/Volumes/test'}];

const res = await dockerSupport.findPathsOutofSharedPaths(mounts);
expect(res).to.eql([]);
});

it('mount paths not shared to docker', async () => {
readFile.returns('{}');
const mounts = [{'Source': '/uuu/test'}, {'Source': '/vvv/test'}];

const res = await dockerSupport.findPathsOutofSharedPaths(mounts);
expect(res).to.eql(['/uuu/test', '/vvv/test']);
});


});
2 changes: 1 addition & 1 deletion test/nas/path.test.js
Expand Up @@ -6,7 +6,7 @@ const mkdirp = require('mkdirp-promise');
const rimraf = require('rimraf');

const expect = require('expect.js');
const USER_HOME = process.env.HOME || process.env.USERPROFILE;
const USER_HOME = require('os').homedir();
const sinon = require('sinon');
const path = require('path');
const sandbox = sinon.createSandbox();
Expand Down

0 comments on commit 04def63

Please sign in to comment.