dockerfile: expose add-hosts

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2018-08-02 12:00:27 -07:00
parent bf29f5bd3b
commit f8b0573edb
2 changed files with 41 additions and 0 deletions

View File

@ -4,8 +4,10 @@ import (
"archive/tar" "archive/tar"
"bytes" "bytes"
"context" "context"
"encoding/csv"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@ -36,6 +38,7 @@ const (
keyTargetPlatform = "platform" keyTargetPlatform = "platform"
keyMultiPlatform = "multi-platform" keyMultiPlatform = "multi-platform"
keyImageResolveMode = "image-resolve-mode" keyImageResolveMode = "image-resolve-mode"
keyGlobalAddHosts = "add-hosts"
) )
var httpPrefix = regexp.MustCompile("^https?://") var httpPrefix = regexp.MustCompile("^https?://")
@ -64,6 +67,11 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) {
return nil, err return nil, err
} }
extraHosts, err := parseExtraHosts(opts[keyGlobalAddHosts])
if err != nil {
return nil, errors.Wrap(err, "failed to parse additional hosts")
}
filename := opts[keyFilename] filename := opts[keyFilename]
if filename == "" { if filename == "" {
filename = defaultDockerfileName filename = defaultDockerfileName
@ -250,6 +258,7 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) {
BuildPlatforms: buildPlatforms, BuildPlatforms: buildPlatforms,
ImageResolveMode: resolveMode, ImageResolveMode: resolveMode,
PrefixPlatform: exportMap, PrefixPlatform: exportMap,
ExtraHosts: extraHosts,
}) })
if err != nil { if err != nil {
@ -413,3 +422,29 @@ func parseResolveMode(v string) (llb.ResolveMode, error) {
return 0, errors.Errorf("invalid image-resolve-mode: %s", v) return 0, errors.Errorf("invalid image-resolve-mode: %s", v)
} }
} }
func parseExtraHosts(v string) ([]llb.HostIP, error) {
if v == "" {
return nil, nil
}
out := make([]llb.HostIP, 0)
csvReader := csv.NewReader(strings.NewReader(v))
fields, err := csvReader.Read()
if err != nil {
return nil, err
}
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) != 2 {
return nil, errors.Errorf("invalid key-value pair %s", field)
}
key := strings.ToLower(parts[0])
val := strings.ToLower(parts[1])
ip := net.ParseIP(val)
if ip == nil {
return nil, errors.Errorf("failed to parse IP %s", val)
}
out = append(out, llb.HostIP{Host: key, IP: ip})
}
return out, nil
}

View File

@ -52,6 +52,7 @@ type ConvertOpt struct {
TargetPlatform *specs.Platform TargetPlatform *specs.Platform
BuildPlatforms []specs.Platform BuildPlatforms []specs.Platform
PrefixPlatform bool PrefixPlatform bool
ExtraHosts []llb.HostIP
} }
func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, *Image, error) { func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, *Image, error) {
@ -294,6 +295,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
cacheIDNamespace: opt.CacheIDNamespace, cacheIDNamespace: opt.CacheIDNamespace,
buildPlatforms: platformOpt.buildPlatforms, buildPlatforms: platformOpt.buildPlatforms,
targetPlatform: platformOpt.targetPlatform, targetPlatform: platformOpt.targetPlatform,
extraHosts: opt.ExtraHosts,
} }
if err = dispatchOnBuild(d, d.image.Config.OnBuild, opt); err != nil { if err = dispatchOnBuild(d, d.image.Config.OnBuild, opt); err != nil {
@ -397,6 +399,7 @@ type dispatchOpt struct {
cacheIDNamespace string cacheIDNamespace string
targetPlatform specs.Platform targetPlatform specs.Platform
buildPlatforms []specs.Platform buildPlatforms []specs.Platform
extraHosts []llb.HostIP
} }
func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error { func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
@ -584,6 +587,9 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE
} }
opt = append(opt, runMounts...) opt = append(opt, runMounts...)
opt = append(opt, llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(dopt.shlex, c.String(), d.state.Run(opt...).Env())), d.prefixPlatform, d.state.GetPlatform()))) opt = append(opt, llb.WithCustomName(prefixCommand(d, uppercaseCmd(processCmdEnv(dopt.shlex, c.String(), d.state.Run(opt...).Env())), d.prefixPlatform, d.state.GetPlatform())))
for _, h := range dopt.extraHosts {
opt = append(opt, llb.AddExtraHost(h.Host, h.IP))
}
d.state = d.state.Run(opt...).Root() d.state = d.state.Run(opt...).Root()
return commitToHistory(&d.image, "RUN "+runCommandString(args, d.buildArgs), true, &d.state) return commitToHistory(&d.image, "RUN "+runCommandString(args, d.buildArgs), true, &d.state)
} }