【发布时间】:2018-02-08 18:24:57
【问题描述】:
系统定义:
2012 macbook pro 运行 Sierra, Docker 版本:17.12.0-ce-mac49 (21995)
问题:
我在容器中使用“coverage run”运行我的 python 应用程序时遇到问题。我将尝试在下面解释我在做什么......希望它是有道理的。尝试在此处提供尽可能多的信息,说明我正在尝试做的事情以及我已经完成的事情。
基本上我的情况是这样的。我正在启动一个基于 python 的(金字塔)网络服务。它只是一个基于 HTTP 的 API。没有什么超级花哨的。当我对它运行邮递员测试时,我想获得它的覆盖率,所以我通过执行“coverage run /path/path/path/app.py”来启动它,并且效果很好。我在要分析的源代码上创建了一个 .coveragerc,将其归零,一切都很好,在容器之外。尝试在我的这个应用的容器化版本中进行覆盖是另一回事。
供参考.. 这是我的 Dockerfile,其中包含用######### 标记掩盖的秘密内容
FROM ################:latest
# Add files
ADD . / /path/
# Set up Env
ENV GRAPHITE_SERVER=localhost
ENV APP_USER=root
ENV APP_HOME=/path
ENV APP_LOGS=$APP_HOME/logs
ENV PYTHONPATH=#################:$PYTHONPATH
ARG requested_environment=stage1
ARG coverage
ARG log_monitor
ENV COVERAGE=$coverage
ENV LOG_MONITOR=$log_monitor
ENV ENVIRONMENT=$requested_environment
ENV PATH=$APP_HOME/######:$PATH
RUN mkdir -p $APP_LOGS
RUN pip install -r $APP_HOME/requirements.txt
RUN cd $APP_HOME/external-libs/mysql-connector/mysql-connector-python-2.1.2/; python setup.py install
RUN ln -fs /usr/bin/python /usr/local/bin/python
EXPOSE 1234
# start app
ENTRYPOINT $COVERAGE $APP_HOME/path/path/app.py $LOG_MONITOR
我的构建命令是
docker build . --build-arg requested_environment=stage1 --build-arg log_monitor=noMonitor --build-arg coverage="coverage run" -t stage1-latest
我想在容器内做与在容器外做同样的事情......意思是......我想在容器内运行应用程序并覆盖。所以你会认为它就像正常构建容器一样简单,入口点通常是
ENTRYPOINT /path/path/path/app.py
changed to
ENTRYPOINT coverage run /path/path/path/app.py
但显然不是。
如果我使用 ENTRYPOINT 或 CMD 启动应用程序来构建容器.. 就像这些.. 是的,我已经尝试了所有这些..
ENTRYPOINT coverage run /path/path/path/app.py
ENTRYPOINT bash -c "coverage run /path/path/path/app.py"
ENTRYPOINT ["bash' "-c","coverage run /path/path/path/app.py"]
ENTRYPOINT ["coverage","run","/path/path/path/app.py"]
CMD coverage run /path/path/path/app.py
CMD ["bash' "-c","coverage run /path/path/path/app.py"]
or
CMD ["coverage","run","/path/path/path/app.py"]
然后像这样启动容器
docker run --name stage1-latest-container-instance -itp 1234:1234 stage1-latest
甚至在 dockerfile 中的 CMD 条目的情况下也是如此(因为它们是默认的,我用这个命令覆盖它们)
docker run --name stage1-latest-container-instance -itp 1234:1234 stage1-latest coverage run /path/path/path/app.py
我的应用程序启动非常好..没有问题..但是
没有创建 .coverage 文件!在容器的文件系统中我没有看到 .coverage 文件。
好的..尝试差异方法
把 dockerfile 改成有
ENTRYPOINT bash
or
CMD bash
重建它...
然后运行容器
docker run --name stage1-latest-container-instance -itp 1234:1234 stage1-latest
这在 docker 容器中给了我一个提示。
[root@ac25fb69bb2e /]#
然后从另一个窗口执行此操作
docker exec -it stage1-latest-container-instance coverage run /path/path/path/app.py
或其他类似 docker exec 的方法
docker exec -it stage1-latest-container-instance bash -c "coverage run /path/path/path/app.py"
还是!不会创建 .coverage 文件。
好的.. 采用差异化方法 我什至创建了一个名为 runapp.sh 的文件并将以下行放入其中
#!/bin/bash
cd /path/path/path && coverage run app.py
然后用
启动容器docker run --name stage1-latest-container-instance -itp 1234:1234 stage1-latest /path/runapp.sh
没有 .coverage 文件 然后我尝试只用
运行容器docker run --name stage1-latest-container-instance -itp 1234:1234 stage1-latest bash
然后从另一个窗口做
docker exec -it stage1-latest-container-instance /path/runapp.sh
仍然没有 .container 文件
好吧..最后的手段..
进入我在交互模式 (-it) 的 dockerfile 中仅使用“CMD bash”运行“docker run”后得到的提示。然后手动启动我的应用程序。
[root@ac25fb69bb2e /]# coverage run /path/path/path/app.py
而且令人惊讶的是.. .coverage 文件的创建没有问题....
什么鬼! 我无法弄清楚这一点..我不知道发生了什么...但是从容器外部对容器执行的命令与在内部的单个外壳内手动执行的命令之间似乎完全断开了容器是否可以创建文件。
请有人告诉我我在这里做错了什么。
我能看到的唯一下一步是在我的应用程序内部使用覆盖模块,并为 KeyboardInterrupt 添加一个异常处理程序,以在应用程序被终止时保存覆盖数据。但这很糟糕。
【问题讨论】:
标签: python docker containers dockerfile coverage.py