Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions image-mapper/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,32 @@ important, where possible, to use tags that are being actively maintained.

Refer to [this page](./docs/map.md) for more details.

### Dockerfile

The `dockerfile` subcommand maps image references in a Dockerfile to Chainguard.

```
$ cat Dockerfile
FROM python:3.13

WORKDIR /app

COPY run.py run.py

ENTRYPOINT ["python", "/app/run.py"]

$ ./image-mapper map dockerfile Dockerfile
FROM cgr.dev/chainguard/python:3.13-dev

WORKDIR /app

COPY run.py run.py

ENTRYPOINT ["python", "/app/run.py"]
```

Refer to [this page](./docs/map_dockerfile.md) for more details.

### Helm

The `helm-chart` and `helm-values` subcommands extract image related values and
Expand Down
1 change: 1 addition & 0 deletions image-mapper/cmd/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func MapCommand() *cobra.Command {
rootCmd.Flags().StringVar(&opts.Repo, "repository", "cgr.dev/chainguard", "Modifies the repository URI in the mappings. For instance, registry.internal.dev/chainguard would result in registry.internal.dev/chainguard/<image> in the output.")

cmd.AddCommand(
MapDockerfileCommand(),
MapHelmChartCommand(),
MapHelmValuesCommand(),
)
Expand Down
65 changes: 65 additions & 0 deletions image-mapper/cmd/map_dockerfile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cmd

import (
"fmt"
"io"
"os"

"github.com/chainguard-dev/customer-success/scripts/image-mapper/internal/dockerfile"
"github.com/chainguard-dev/customer-success/scripts/image-mapper/internal/mapper"
"github.com/spf13/cobra"
)

func MapDockerfileCommand() *cobra.Command {
opts := struct {
Repo string
}{}
cmd := &cobra.Command{
Use: "dockerfile",
Short: "Map image references in a Dockerfile to their Chainguard equivalents.",
Example: `
# Map a Dockerfile
image-mapper map dockerfile Dockerfile

# Map a Dockerfile from stdin
cat Dockerfile | image-mapper map dockerfile -

# Override the repository in the mappings with your own mirror or proxy. For instance, cgr.dev/chainguard/<image> would become registry.internal/cgr/<image> in the output.
image-mapper map dockerfile Dockerfile --repository=registry.internal/cgr
`,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var (
input []byte
err error
)
switch args[0] {
case "-":
input, err = io.ReadAll(os.Stdin)
if err != nil {
return fmt.Errorf("reading stdin: %w", err)
}
default:
input, err = os.ReadFile(args[0])
if err != nil {
return fmt.Errorf("reading file: %s: %w", args[0], err)
}
}

output, err := dockerfile.Map(cmd.Context(), input, mapper.WithRepository(opts.Repo))
if err != nil {
return fmt.Errorf("mapping dockerfile: %w", err)
}

if _, err := os.Stdout.Write(output); err != nil {
return fmt.Errorf("writing output: %w", err)
}

return nil
},
}

cmd.Flags().StringVar(&opts.Repo, "repository", "cgr.dev/chainguard", "Modifies the repository URI in the mappings. For instance, registry.internal.dev/chainguard would result in registry.internal.dev/chainguard/<image> in the output.")

return cmd
}
107 changes: 107 additions & 0 deletions image-mapper/docs/map_dockerfile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Map Dockerfile

Map images references in a Dockerfile to Chainguard images.

## How It Works

The `dockerfile` subcommand maps any image references it finds in `FROM <image>`,
`COPY --from=<image>` or `RUN --mount-type=bind,from=<image>` directives to
Chainguard.

It will map images to `-dev` tags because they are more likely to work out of
the box as drop in replacements.

## Basic Usage

Given a `Dockerfile` like this:

```
FROM python:3.13 AS python

WORKDIR /app

COPY run.py run.py

ENTRYPOINT ["python", "/app/run.py"]
```

Use the `dockerfile` subcommand to map it to Chainguard images. It returns the
result to stdout.

```
$ ./image-mapper map dockerfile Dockerfile
FROM cgr.dev/chainguard/python:3.13-dev

WORKDIR /app

COPY run.py run.py

ENTRYPOINT ["python", "/app/run.py"]
```

You can also provide the Dockerfile via stdin:

```
$ cat Dockerfile | ./image-mapper map dockerfile -
```

## Repository Prefix

Use the `--repository` flag to replace `cgr.dev/chainguard` with a custom
repository.

```
$ ./image-mapper map dockerfile Dockerfile --repository=registry.internal/cgr
FROM registry.internal/cgr/python:3.13-dev

WORKDIR /app

COPY run.py run.py

ENTRYPOINT ["python", "/app/run.py"]
```

## Known Limitations

There are a few rough edges that haven't been smoothed out yet.

### Args

The mapper supports resolving arguments to figure out which images they refer
to but it isn't clever enough to go back and update those arguments.

For instance, a file like this:

```
ARG REGISTRY=docker.io
ARG IMAGE=library/python
ARG TAG=3.13
FROM ${REGISTRY}/${IMAGE}:${TAG}
```

Would become:

```
ARG REGISTRY=docker.io
ARG IMAGE=library/python
ARG TAG=3.13
FROM cgr.dev/chainguard/python:3.13-dev
```

### Multi Line Directives

If it updates an image reference in a multi line directive then it will squash
the directive into one line.

For instance, lines like this:

```
RUN --mount=type=bind,from=ubuntu,target=/bin/cat \
cat run.py
```

Would become:

```
RUN --mount=type=bind,from=cgr.dev/chainguard/chainguard-base:latest,target=/bin/cat cat run.py
```
21 changes: 12 additions & 9 deletions image-mapper/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.24.5
require (
github.com/google/go-cmp v0.7.0
github.com/google/go-containerregistry v0.20.6
github.com/moby/buildkit v0.26.3
github.com/spf13/cobra v1.10.1
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.19.4
Expand All @@ -25,13 +26,14 @@ require (
github.com/containerd/containerd v1.7.29 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/platforms v1.0.0-rc.2 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
Expand All @@ -54,14 +56,14 @@ require (
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/compress v1.18.1 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
Expand All @@ -77,6 +79,7 @@ require (
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rubenv/sql-migrate v1.8.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
Expand All @@ -96,10 +99,10 @@ require (
golang.org/x/sys v0.38.0 // indirect
golang.org/x/term v0.37.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/time v0.12.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/grpc v1.72.1 // indirect
google.golang.org/protobuf v1.36.5 // indirect
golang.org/x/time v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
google.golang.org/grpc v1.76.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/api v0.34.2 // indirect
Expand Down
Loading
Loading