Review config for cmd/entrypoint after building a stage
As mentioned in #346, if only ENTRYPOINT is set in a stage then any CMD inherited from a parent should be cleared. If both entrypoint and cmd are set then nothing should change. I added a function and unit test to review the config file after building a stage which clears out config.Cmd if ENTRYPOINT was declared but CMD wasn't. I also added an integration test to make sure this works, which should be tested by the preexisting container-diff --metadata test.
This commit is contained in:
parent
4dc34343b6
commit
5d2d2829d0
|
|
@ -0,0 +1,5 @@
|
|||
FROM scratch AS first
|
||||
CMD ["mycmd"]
|
||||
|
||||
FROM first
|
||||
ENTRYPOINT ["myentrypoint"] # This should clear out CMD in the config metadata
|
||||
|
|
@ -145,6 +145,9 @@ func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := reviewConfig(stage, &imageConfig.Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sourceImage, err = mutate.Config(sourceImage, imageConfig.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -228,3 +231,24 @@ func resolveOnBuild(stage *config.KanikoStage, config *v1.Config) error {
|
|||
config.OnBuild = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// reviewConfig makes sure the value of CMD is correct after building the stage
|
||||
// If ENTRYPOINT was set in this stage but CMD wasn't, then CMD should be cleared out
|
||||
// See Issue #346 for more info
|
||||
func reviewConfig(stage config.KanikoStage, config *v1.Config) error {
|
||||
entrypoint := false
|
||||
cmd := false
|
||||
|
||||
for _, c := range stage.Commands {
|
||||
if c.Name() == "cmd" {
|
||||
cmd = true
|
||||
}
|
||||
if c.Name() == "entrypoint" {
|
||||
entrypoint = true
|
||||
}
|
||||
}
|
||||
if entrypoint && !cmd {
|
||||
config.Cmd = []string{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package executor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
||||
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||
"github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
func Test_reviewConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dockerfile string
|
||||
originalCmd []string
|
||||
originalEntrypoint []string
|
||||
expectedCmd []string
|
||||
}{
|
||||
{
|
||||
name: "entrypoint and cmd declared",
|
||||
dockerfile: `
|
||||
FROM scratch
|
||||
CMD ["mycmd"]
|
||||
ENTRYPOINT ["myentrypoint"]`,
|
||||
originalEntrypoint: []string{"myentrypoint"},
|
||||
originalCmd: []string{"mycmd"},
|
||||
expectedCmd: []string{"mycmd"},
|
||||
},
|
||||
{
|
||||
name: "only entrypoint declared",
|
||||
dockerfile: `
|
||||
FROM scratch
|
||||
ENTRYPOINT ["myentrypoint"]`,
|
||||
originalEntrypoint: []string{"myentrypoint"},
|
||||
originalCmd: []string{"mycmd"},
|
||||
expectedCmd: []string{},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
config := &v1.Config{
|
||||
Cmd: test.originalCmd,
|
||||
Entrypoint: test.originalEntrypoint,
|
||||
}
|
||||
err := reviewConfig(stage(t, test.dockerfile), config)
|
||||
testutil.CheckErrorAndDeepEqual(t, false, err, test.expectedCmd, config.Cmd)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func stage(t *testing.T, d string) config.KanikoStage {
|
||||
stages, err := dockerfile.Parse([]byte(d))
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing dockerfile: %v", err)
|
||||
}
|
||||
return config.KanikoStage{
|
||||
Stage: stages[0],
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue