docker / buildx

Docker CLI plugin for extended build capabilities with BuildKit
Apache License 2.0
3.56k stars 481 forks source link

docker-bake.json applying HCL string templates #2613

Open amartani opened 3 months ago

amartani commented 3 months ago

Contributing guidelines

I've found a bug and checked that ...

Description

When using docker bake with a JSON docker bake config, strings are being parsed as if they were HCL strings (applying HCL string template interpolation / directives).

Expected behaviour

Expected the JSON file to be parsed as a JSON file, such that strings on it are not further processed as HCL templates. In the example below, I expect the image to be build and labeled with the foo label getting the literal value %{bar}.

Actual behaviour

On the example below, parsing the docker-bake.json fails, as it tries to parse as HCL template.

Buildx version

github.com/docker/buildx v0.13.0 0de5f1c

Docker info

docker info          
Client: Docker Engine - Community
 Version:    25.0.4
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.13.0
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.24.7
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 14
  Running: 0
  Paused: 0
  Stopped: 14
 Images: 55
 Server Version: 25.0.4
 Storage Driver: overlay2
  Backing Filesystem: btrfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: d2d58213f83a351ca8f528a95fbd145f5654e957
 runc version: v1.1.12-0-g51d5e94
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 6.7.11-orbstack-00143-ge6b82e26cd22
 Operating System: Ubuntu 20.04.6 LTS
 OSType: linux
 Architecture: aarch64
 CPUs: 12
 Total Memory: 19.5GiB
 Name: dc773ac7bce3
 ID: daf97268-48c1-44df-a7ce-b588fa71dcfb
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

Builders list

NAME/NODE                            DRIVER/ENDPOINT                   STATUS     BUILDKIT   PLATFORMS  
default*                             docker                                                  
 \_ default                           \_ default                       running    v0.12.5    linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/arm/v7, linux/arm/v6

Configuration

docker-bake.json

{
  "target": {
    "default": {
      "dockerfile": "Dockerfile",
      "tags": ["webapp:latest"],
      "labels": {
        "foo": "%{bar}"
      }
    }
  }
}

Build logs

$ docker buildx bake
[+] Building 0.0s (1/1) FINISHED                                                                                                                                     docker:default
 => [internal] load local bake definitions                                                                                                                                     0.0s
 => => reading docker-bake.json 162B / 162B                                                                                                                                    0.0s
docker-bake.json:7
--------------------
   5 |           "tags": ["webapp:latest"],
   6 |           "labels": {
   7 | >>>         "foo": "%{bar}"
   8 |           }
   9 |         }
--------------------
ERROR: docker-bake.json:7,19-22: Invalid template control keyword; "bar" is not a valid template control keyword. Did you mean "for"?, and 1 other diagnostic(s)

Additional info

We use the json format of docker bake as we prefer to programmatically generate JSON instead of manually editing HCL. I expect that this would be the most common case for using JSON.

When generating JSON config programmatically, applying HCL string templates is both undesired (we would prefer to do any manipulation on the input before generating the JSON) and also dangerous (it can end up violating validations that we perform before generating the JSON file).

If the current behavior is working as intended, it should at least be documented as such, as the behavior is surprising when programmatically generating raw JSON objects.

tonistiigi commented 3 months ago

I think there are cases where access to variables and directives would be useful from JSON format. If you want raw strings then these can be escaped with %% or $$.

It does look that atm when using --print with an escaped value we would print the "%{bar}" directly. That does not look correct as I think the output of --print should be usable as input. I think we should escape the output of --print (unless we want to make loading raw json vs JSON-with-templates configurable somehow).