mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 09:16:29 +00:00
Ability to parse args from Dockerfile
We should check if we have args in "FROM" and replace them: ARG IMAGE=linuxkit/img FROM ${IMAGE} as src will be parsed as FROM linuxkit/img as src Signed-off-by: Petr Fedchenkov <giggsoff@gmail.com>
This commit is contained in:
parent
403e8f9353
commit
5763c4f4bc
@ -37,6 +37,7 @@ import (
|
||||
"github.com/moby/buildkit/frontend/dockerfile/builder"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/parser"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/shell"
|
||||
"github.com/moby/buildkit/session/upload/uploadprovider"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -446,30 +447,57 @@ func (dr *dockerRunnerImpl) build(ctx context.Context, tag, pkg, dockerContext,
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing dockerfile from bytes into AST %s: %v", dockerfile, err)
|
||||
}
|
||||
stages, _, err := instructions.Parse(ast.AST)
|
||||
stages, metaArgs, err := instructions.Parse(ast.AST)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing dockerfile from AST into stages %s: %v", dockerfile, err)
|
||||
}
|
||||
|
||||
// fill optMetaArgs with args found while parsing Dockerfile
|
||||
optMetaArgs := make(map[string]string)
|
||||
for _, cmd := range metaArgs {
|
||||
for _, metaArg := range cmd.Args {
|
||||
optMetaArgs[metaArg.Key] = metaArg.ValueString()
|
||||
}
|
||||
}
|
||||
// replace parsed args with provided BuildArgs if keys found
|
||||
for k, v := range imageBuildOpts.BuildArgs {
|
||||
if _, found := optMetaArgs[k]; found {
|
||||
optMetaArgs[k] = *v
|
||||
}
|
||||
}
|
||||
|
||||
shlex := shell.NewLex(ast.EscapeToken)
|
||||
// go through each stage, get the basename of the image, see if we have it in the linuxkit cache
|
||||
imageStores := map[string]string{}
|
||||
for _, stage := range stages {
|
||||
// check if we have args in FROM and replace them:
|
||||
// ARG IMAGE=linuxkit/img
|
||||
// FROM ${IMAGE} as src
|
||||
// will be parsed as:
|
||||
// FROM linuxkit/img as src
|
||||
name, err := shlex.ProcessWordWithMap(stage.BaseName, optMetaArgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not process word for image %s: %v", stage.BaseName, err)
|
||||
}
|
||||
if name == "" {
|
||||
return fmt.Errorf("base name (%s) should not be blank", stage.BaseName)
|
||||
}
|
||||
// see if the provided image name is tagged (docker.io/linuxkit/foo:latest) or digested (docker.io/linuxkit/foo@sha256:abcdefg)
|
||||
// if neither, we have an error
|
||||
ref, err := reference.Parse(util.ReferenceExpand(stage.BaseName))
|
||||
ref, err := reference.Parse(util.ReferenceExpand(name))
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not resolve references for image %s: %v", stage.BaseName, err)
|
||||
return fmt.Errorf("could not resolve references for image %s: %v", name, err)
|
||||
}
|
||||
gdesc, err := c.FindDescriptor(&ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid name %s", stage.BaseName)
|
||||
return fmt.Errorf("invalid name %s", name)
|
||||
}
|
||||
// not found, so nothing to look up
|
||||
if gdesc == nil {
|
||||
continue
|
||||
}
|
||||
hash := gdesc.Digest
|
||||
imageStores[stage.BaseName] = hash.String()
|
||||
imageStores[name] = hash.String()
|
||||
}
|
||||
if len(imageStores) > 0 {
|
||||
// if we made it here, we found the reference
|
||||
|
@ -0,0 +1,5 @@
|
||||
ARG IMAGE=alpine
|
||||
ARG TAG=3.15
|
||||
FROM ${IMAGE}:${TAG}
|
||||
|
||||
COPY foo /foo
|
@ -0,0 +1,5 @@
|
||||
image: chained-build-with-args-image1-test-does-not-exist-anywhere-else-123456789 # this must be used as FROM in the chained image
|
||||
network: true
|
||||
arches:
|
||||
- amd64
|
||||
- arm64
|
@ -0,0 +1 @@
|
||||
bar
|
@ -0,0 +1,7 @@
|
||||
# those IMAGE and TAG *must* be updated when changing ../build1; just run `lkt pkg show-tag ../build1` and place it here
|
||||
ARG IMAGE=linuxkit/chained-build-with-args-image1-test-does-not-exist-anywhere-else-123456789
|
||||
ARG TAG=6a40ba0866b7ce18b3b13390bf88bfeb6ac0db4e
|
||||
FROM ${IMAGE}:${TAG} as src
|
||||
FROM alpine:3.15
|
||||
COPY --from=src /foo /foo
|
||||
RUN cat /foo
|
@ -0,0 +1,5 @@
|
||||
image: chained-build-with-args-test-second
|
||||
network: true
|
||||
arches:
|
||||
- amd64
|
||||
- arm64
|
19
test/cases/000_build/041_chained_builds_with_args/test.sh
Executable file
19
test/cases/000_build/041_chained_builds_with_args/test.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
# SUMMARY: Check that chained builds support args
|
||||
# LABELS:
|
||||
# REPEAT:
|
||||
|
||||
set -ex
|
||||
|
||||
# Source libraries. Uncomment if needed/defined
|
||||
#. "${RT_LIB}"
|
||||
. "${RT_PROJECT_ROOT}/_lib/lib.sh"
|
||||
|
||||
# Test code goes here
|
||||
echo linuxkit is "$(which linuxkit)"
|
||||
|
||||
# build the first, use it to build the second
|
||||
linuxkit pkg build --force ./build1
|
||||
linuxkit pkg build --force ./build2
|
||||
|
||||
exit 0
|
Loading…
Reference in New Issue
Block a user