Search code examples
dockerkubernetespostmanargsnewman

Kubernetes container args behave incorrect


I want to use Kubernetes and the postman/newman Docker image to execute my API tests.

Locally, I can execute the image with

docker run postman/newman run <url-to-collection> --env-var baseUrl=<local-hostname>

I include the Image in a Kubernetes manifest file

spec:
  containers:
    - name: newman
      image: postman/newman:latest
      args:
        - run
        - '<url-to-collection>'
        - --env-var baseUrl=<kubernetes-hostname>

When I apply the manifest and look at the logs of the container, I get the following error:

error: unknown option '--global-var baseUrl=<kubernetes-hostname>'

I tried out many things with quotes and using the command section instead of the args section, but always with the same result. I figure that Kubernetes somehow builds the command in a way, that the newman executable can not understand it. However I could not find any info about that.

(I also created an issue in the GitHub repo of Newman here)

Could anybody explain to me where this problem comes from and how I might solve this?

Thanks anyways!


Solution

  • Linux commands are made up of a sequence of words. If you type a command at a shell prompt, it takes responsibility for splitting it into words for you, but in the Kubernetes args: list, you need to split out the words yourself.

    args:
      - run
      - '<url-to-collection>'
      # You want these as two separate arguments, so they need to be
      # two separate list items
      - --env-var
      - baseUrl=<kubernetes-hostname>
    

    If the two arguments are in the same list item, they are a single "word":

    # /bin/ls "/app/some directory/some file"
    command:
      - /bin/ls
      # a single argument, including embedded spaces
      - /app/some directory/some file
    

    The same basic rules apply for Docker Compose entrypoint: and command: and the JSON-syntax Dockerfile ENTRYPOINT and CMD directives, except that the Docker-native forms all also accept a plain string that they will split on spaces (using a shell in the Dockerfile case, but not in the Compose case).

    In the docker run command you provide, the shell on your host system processes it first, so the --env-var option and baseUrl=... argument get split into separate words before they're passed into the container.