buildkite-plugins / docker-buildkite-plugin

🐳📦 Run any build step in a Docker container
MIT License
112 stars 106 forks source link

Handling of parameters when shell is false #227

Closed ghost closed 1 year ago

ghost commented 2 years ago

Version: v5.3.0 When using a docker image that doesn't have a shell, there is an issue when passing several parameters. Please look at the example below: `

$ docker run -t -i --rm --init --volume /buildkite/builds/buildkite-agent-8454df698b-qbq2d-1/bose/terraform-zonenetwork-pull-request:/workdir --workdir /workdir --label com.buildkite.job-id=01848b76-4680-4a10-a6b3-745d9cd6e37a ghcr.io/terraform-linters/tflint-bundle:latest --force\ --enable-plugin=aws

Failed to parse CLI options; force --enable-plugin is unknown option. Please run tflint --help `

The problem seems that the backlash character ('\') between the options is causing an issue. In my opinion, if shell is set as false, this backlash shouldn't be added. If there is a workaround to this issue, please let me know.

Thanks in advance

toote commented 2 years ago

@GuillermoContrerasP that is an interesting issue, could you share the step that caused that?

ghost commented 2 years ago

Sure thing. Here is the step definition that caused the issue:

steps:

toote commented 2 years ago

@GuillermoContrerasP quite interesting... the plugin is indeed passing the command string as-is, but it is a single string so it is intepreted as a single string that contains a space.

A possible workaround is to use the plugin's command to split them into an array:

steps:
  - label: "Terraform linting command"
    plugins:
      - docker#v5.3.0:
          image: "ghcr.io/terraform-linters/tflint-bundle:latest"
          always-pull: true
          shell: false
          command:
            - "--force"
            - "--enable-plugin=aws"

I'm not sure if the assumption that a lack of shell should mean that the step level command needs to be split on spaces. Will leave this ticket open and review what can be done about that use case, though.

toote commented 1 year ago

@GuillermoContrerasP I've spent a lot of time playing around with different scenarios and couldn't work around some pretty basic scenarios.

The main fact is that the command is only available as a single string (as you experienced). To be able to pass the command through to the entrypoint it needs to be split out... and there is no reliable way to do that without running into globbing and escaping issues. So a command like --option="with spaces" -g * would get split into 4 or more strings: --option="with, spaces" and -g and the rest of the elements may involve bash expanding the * (depending on how you try to split it out).

The surefire way to ensure that commands are split correctly is using the plugin's command option as mentioned in my previous comment.