Docker deploy_container sends literal None command when command is omitted

Open Beginner friendly
#2,226 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
docker, python
Domain
cloud

Research direction

Start in DockerContainerDriver.deploy_container() in libcloud/container/drivers/docker.py, where command = shlex.split(str(command)) runs before the create payload is built. Run the reproduction script in the issue to confirm Cmd is ['None'] when the argument is omitted. Done when omitting command or passing None leaves Cmd out of the request, and explicit strings such as 'echo "hello world"' still split into arguments.

Written by the indexing model from the issue text.

Description

Summary

DockerContainerDriver.deploy_container() turns its default command=None into the literal command ['None'] in the container-create request. Omitting the argument therefore sends an explicit command override rather than leaving the image's default command alone.

The documented Docker example calls deploy_container('tomcat', image) without a command.

Detailed Information

Observed on unchanged trunk 8a0ef6260680625d54fce5093d2315e0926a7dc9, Libcloud 4.0.0.dev0, Python 3.12/Linux. This is a request-serialization reproduction using the actual driver method with API-version negotiation and response transport substituted. No Docker daemon/container was started.

import json
from types import SimpleNamespace
from unittest.mock import patch
from libcloud.container.drivers.docker import DockerContainerDriver
from libcloud.container.base import ContainerImage

with patch.object(DockerContainerDriver, '_get_api_version', return_value='1.24'):
    driver = DockerContainerDriver()
image = ContainerImage('i', 'test-image', 'test-image', 'latest', driver)

for kwargs in ({}, {'command': None}, {'command': ''},
               {'command': 'echo "hello world"'}):
    requests = []
    def request(action, **options):
        requests.append((action, options))
        body = {'Id': 'local-probe'} if action.endswith('/create') else {
            'Id': 'local-probe', 'Name': '/local-probe',
            'Image': 'test-image', 'Status': 'Created', 'Ports': []}
        return SimpleNamespace(object=body)
    driver.connection = SimpleNamespace(request=request, driver=driver)
    driver.deploy_container('local-probe', image, start=False, **kwargs)
    print(kwargs, json.loads(requests[0][1]['data'])['Cmd'])

Output:

{} ['None']
{'command': None} ['None']
{'command': ''} []
{'command': 'echo "hello world"'} ['echo', 'hello world']

The cause is command = shlex.split(str(command)) before building the payload. The optional absent value is converted to text before splitting. Expected: preserve the no-command-override case while retaining parsing of explicit command strings.

Docker's CMD documentation describes the image command as a default, overridden by supplied command arguments. This report establishes the incorrect outgoing Cmd, not a live-daemon startup error or full-suite result. No production code change yet.

AI assistance: ChatGPT helped investigate, reproduce, and draft this report.

Dominant language
Python
Stars
2.1k
Forks
935
Avg merge
5d 3h
Merged PRs (30d)
15

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/libcloud

All issues in apache/libcloud

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.