将oracledb集成到cloudfoundry自定义buildpack中

时间:2018-02-13 23:09:35

标签: cloudfoundry

我们的目标是将我们的node.js webservice集成到cloudfoundry中。由于我们需要oracledb模块来访问我们的数据库,因此我们不得不创建一个自定义buildpack(从cloudfoundry / nodejs-buildpack派生),它安装了所需的oracle instantclient。

s.Stager.BuildDir() + '/instantclient-basic'目录中下载并解压缩instantclient和sdk后,似乎我们必须将LD_LIBRARY_PATH变量设置为此路径。

因此,在/src/nodejs/supply/supply.go文件中,我们添加了以下代码行:

if err := s.Stager.WriteEnvFile("LD_LIBRARY_PATH", filepath.Join(s.Stager.BuildDir(), "instantclient-basic")); err != nil {
    return err
}

但是,在安装此buildpack时的日志输出中,它列出了其他变量,如NODE_ENVNODE_HOME(设置方式完全相同),我的变量LD_LIBRARY_PATH丢失了。如何正确导出新的env变量?

----编辑回应Daniel Mikusa的答案---

我尝试关注.profile,包括instantclient文件方法:

- controllers
- public
- instantclient
| --- libclntsh.so
| ... 
app.js
server.js
package.json
.profile

这是.profile文件的样子:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/app/instantclient

但是,当我创建一个.zip,并在我们的cloundfoundry上创建一个新的nodejs buildpack时,我得到了和以前一样的错误:

  

ERR错误:NJS-045:无法加载Node.js 6.11.2(linux,64)的oracledb附加二进制文件

     

ERR Node.js require()错误是:

     

ERR DPI-1047:无法加载64位Oracle客户端库:“libclntsh.so:无法打开共享对象文件:没有此类文件或目录”。

你觉得这里有什么错吗?

1 个答案:

答案 0 :(得分:1)

我将从这里引用buildpack合同文档开始。

https://docs.cloudfoundry.org/buildpacks/custom.html#contract

您正在呼叫s.Stager.WriteEnvFile,您可以在此处查看来源。

https://github.com/cloudfoundry/libbuildpack/blob/e915de2390c8dcc4f3a05dd747c7635454335e26/stager.go#L76

此方法正在编写env文件。来自buildpack文档...

  

可以在/ tmp / deps / IDX /中创建以下目录,以便为后续构建包提供依赖关系:

     

...

     
      
  • /env:包含用于登台的环境变量,加载为FILENAME = FILECONTENTS
  •   

所以你添加的内容应该创建一个后续buildpack可以使用的env文件。这是你想要的吗?

如果要在运行时设置env变量(即运行应用程序时),则需要修改buildpack的这一部分。

https://github.com/cloudfoundry/nodejs-buildpack/blob/master/src/nodejs/supply/supply.go#L586-L593

    scriptContents := `export NODE_HOME=%s
export NODE_ENV=${NODE_ENV:-production}
export MEMORY_AVAILABLE=$(echo $VCAP_APPLICATION | jq '.limits.mem')
export WEB_MEMORY=${WEB_MEMORY:-512}
export WEB_CONCURRENCY=${WEB_CONCURRENCY:-1}
export LD_LIBRARY_PATH=/path/to/instant-client
`

    return s.Stager.WriteProfileD("node.sh", fmt.Sprintf(scriptContents, filepath.Join("$DEPS_DIR", s.Stager.DepsIdx(), "node")))

只需确保/path/to/instant-client在运行时容器中相关,而不是在暂存容器中。路径可以不同。

对于它的价值,如果你有很多需要这种调整的应用程序,我只建议分配buildpack。它需要维护以保持buildpack的最新状态,并且您不希望您的fork落后或者您可能会遇到运行旧版本节点或者您的buildpack提供的任何二进制文件(可能存在安全漏洞)的问题。

如果您只有几个应用程序,则应该能够将即时客户端与应用程序文件捆绑在一起。为此,只需将即时客户端解压缩到项目文件夹的子文件夹即可。然后将名为.profile的文件添加到项目文件夹的根目录中。在该文件中,添加LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/app/instant-client-folder

当您推送应用时,将会获取.profile文件。这会将即时客户端文件夹附加到LD_LIBRARY_PATH环境变量,该变量应该可供您的应用程序使用。

此处.profile的更多详细信息 - > https://docs.cloudfoundry.org/devguide/deploy-apps/deploy-app.html#profile