0
$\begingroup$

Rosanswers logo

I want to run a docker container wrapping ROS indigo using docker-py without running a command.

>>> import docker
>>> docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock')
>>> container = docker_client.containers.run(image="osrf/ros:indigo-desktop-trusty", detach=True, tty=True)

According to docker container ls the container is running. /ros_entrypoint.sh as COMMAND made me think the entry point script is executed when the container is run.

CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS               NAMES
69b97aa978f1        osrf/ros:indigo-desktop-trusty   "/ros_entrypoint.s..."   2 minutes ago       Up 2 minutes                            festive_lichterman

However when I call a ros command line tool in the container

>>> logs = container.exec_run(cmd='rosparam list')
>>> print(logs)

I get this error

ExecResult(exit_code=126, output='rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "exec: \\"rosparam\\": executable file not found in $PATH"\n\r\n')

with possible root cause that (a) the entry point script is not executed when the container is run or (b) that exec_run() is executed in another shell which has entry point script not executed.

Does someone have an idea about how to reliably source the env when executing subsequent commands in docker containers using docker-py?

EDIT:

The behavior described above corresponds to the following docker command line observation. If one executes subsequent commands they are executed in separate bash session which lack sourcing of the environment. (rosversion does not depend on sourced environment and is executable.)

kromer@rc-019:~/ws_gitlab$ docker run --name roscli --rm -i -t -d osrf/ros:indigo-desktop-full bash
ecd86cd4df75ff316738364fac64cd5afa43d7799e014b3e399dc1a58a2e1a66
kromer@rc-019:~/ws_gitlab$ docker container ls
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS               NAMES
ecd86cd4df75        osrf/ros:indigo-desktop-full   "/ros_entrypoint.s..."   3 seconds ago       Up 1 second                             roscli
kromer@rc-019:~/ws_gitlab$ docker exec roscli rosparam
rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "exec: \"rosparam\": executable file not found in $PATH"

If one attaches to the containers initial bash session the environment is sourced and e.g. rosparam gives expected output:

kromer@rc-019:~/ws_gitlab$ docker run --name roscli --rm -i -t -d osrf/ros:indigo-desktop-full bash
f6ab686c8477a14be65b1d16b66bf95fc94c92891c04551c94b8dad5662cd469
kromer@rc-019:~/ws_gitlab$ docker attach roscli
root@f6ab686c8477:/# rosparam
rosparam is a command-line tool for getting, setting, and deleting parameters from the ROS Parameter Server.

Commands:
    rosparam set    set parameter
    rosparam get    get parameter
    rosparam load   load parameters from file
    rosparam dump   dump parameters to file
    rosparam delete delete parameter
    rosparam list   list parameter names

root@f6ab686c8477:/# exit
exit
kromer@rc-019:~/ws_gitlab$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Originally posted by thinwybk on ROS Answers with karma: 468 on 2018-08-03

Post score: 0


Original comments

Comment by thinwybk on 2018-08-03:
rosversion does not seem to depend on sourcing: It can be called as subsequent command with logs = container.exec_run(cmd='rosversion') which gives a reasonable output ExecResult(exit_code=64, output='Usage: rosversion <package/stack> or rosversion -d\n').

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

The probably most easy solution is to put the the call of /ros_entrypoint.sh in front of the actual command. (This works because ros_entrypoint.sh calls the argument passed...)

>>> import docker
>>> docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock')
>>> container = docker_client.containers.run(image="osrf/ros:indigo-desktop-trusty", detach=True, tty=True)
>>> logs = container.exec_run(cmd='/ros_entrypoint.sh rosparam list')
>>> print(logs)
ExecResult(exit_code=1, output='ERROR: Unable to communicate with master!\n')

Originally posted by thinwybk with karma: 468 on 2018-08-06

This answer was ACCEPTED on the original site

Post score: 0

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.