Add --ignore flag

Added a --ignore flag to ignore packages and files in the build context.
This should mimic the .dockerignore file. Before starting the build, we
go through and delete ignored files from the build context.
This commit is contained in:
Priya Wadhwa 2018-10-12 11:55:09 -07:00
parent 72e088fda5
commit a572774bbe
5 changed files with 96 additions and 3 deletions

View File

@ -321,6 +321,10 @@ _This flag must be used in conjunction with the `--cache=true` flag._
Set this flag to cleanup the filesystem at the end, leaving a clean kaniko container (if you want to build multiple images in the same container, using the debug kaniko image)
#### --ignore
Set this flag to ignore files in your build context. For examples, set `--ignore pkg/*` to ignore all files in the `pkg` directory.
### Debug Image
The kaniko executor image is based off of scratch and doesn't contain a shell.

View File

@ -61,6 +61,9 @@ var RootCmd = &cobra.Command{
if err := resolveSourceContext(); err != nil {
return errors.Wrap(err, "error resolving source context")
}
if err := removeIgnoredFiles(); err != nil {
return errors.Wrap(err, "error removing ignored files from build context")
}
return resolveDockerfilePath()
},
Run: func(cmd *cobra.Command, args []string) {
@ -91,6 +94,7 @@ func addKanikoOptionsFlags(cmd *cobra.Command) {
RootCmd.PersistentFlags().VarP(&opts.Destinations, "destination", "d", "Registry the final image should be pushed to. Set it repeatedly for multiple destinations.")
RootCmd.PersistentFlags().StringVarP(&opts.SnapshotMode, "snapshotMode", "", "full", "Change the file attributes inspected during snapshotting")
RootCmd.PersistentFlags().VarP(&opts.BuildArgs, "build-arg", "", "This flag allows you to pass in ARG values at build time. Set it repeatedly for multiple values.")
RootCmd.PersistentFlags().VarP(&opts.Ignore, "ignore", "", "Set this flag to ignore files in the build context. Set it repeatedly for multiple values.")
RootCmd.PersistentFlags().BoolVarP(&opts.InsecurePush, "insecure", "", false, "Push to insecure registry using plain HTTP")
RootCmd.PersistentFlags().BoolVarP(&opts.SkipTLSVerify, "skip-tls-verify", "", false, "Push to insecure registry ignoring TLS verify")
RootCmd.PersistentFlags().StringVarP(&opts.TarPath, "tarPath", "", "", "Path to save the image in as a tarball instead of pushing")
@ -182,6 +186,35 @@ func resolveSourceContext() error {
return nil
}
func removeIgnoredFiles() error {
logrus.Infof("Removing ignored files from build context: %s", opts.Ignore)
for r, i := range opts.Ignore {
opts.Ignore[r] = filepath.Clean(filepath.Join(opts.SrcContext, i))
}
err := filepath.Walk(opts.SrcContext, func(path string, fi os.FileInfo, _ error) error {
if ignoreFile(path) {
if err := os.RemoveAll(path); err != nil {
logrus.Debugf("error removing %s from buildcontext", path)
}
}
return nil
})
return err
}
func ignoreFile(path string) bool {
for _, i := range opts.Ignore {
matched, err := filepath.Match(i, path)
if err != nil {
return false
}
if matched {
return true
}
}
return false
}
func exit(err error) {
fmt.Println(err)
os.Exit(1)

View File

@ -0,0 +1,2 @@
FROM scratch
COPY . .

View File

@ -54,6 +54,16 @@ var argsMap = map[string][]string{
"Dockerfile_test_multistage": {"file=/foo2"},
}
var filesToIgnore = []string{"context/bar/*", "context/tars/"}
func ignoreFlags() []string {
var f []string
for _, i := range filesToIgnore {
f = append(f, fmt.Sprintf("--ignore=%s", i))
}
return f
}
// Arguments to build Dockerfiles with when building with docker
var additionalDockerFlagsMap = map[string][]string{
"Dockerfile_test_target": {"--target=second"},
@ -64,6 +74,7 @@ var additionalKanikoFlagsMap = map[string][]string{
"Dockerfile_test_add": {"--single-snapshot"},
"Dockerfile_test_scratch": {"--single-snapshot"},
"Dockerfile_test_target": {"--target=second"},
"Dockerfile_test_ignore": ignoreFlags(),
}
var bucketContextTests = []string{"Dockerfile_test_copy_bucket"}
@ -110,9 +121,10 @@ func FindDockerFiles(dockerfilesPath string) ([]string, error) {
// keeps track of which files have been built.
type DockerFileBuilder struct {
// Holds all available docker files and whether or not they've been built
FilesBuilt map[string]bool
DockerfilesToIgnore map[string]struct{}
TestCacheDockerfiles map[string]struct{}
FilesBuilt map[string]bool
DockerfilesToIgnore map[string]struct{}
TestCacheDockerfiles map[string]struct{}
TestIgnoreDockerfiles map[string]struct{}
}
// NewDockerFileBuilder will create a DockerFileBuilder initialized with dockerfiles, which
@ -130,6 +142,9 @@ func NewDockerFileBuilder(dockerfiles []string) *DockerFileBuilder {
"Dockerfile_test_cache": {},
"Dockerfile_test_cache_install": {},
}
d.TestIgnoreDockerfiles = map[string]struct{}{
"Dockerfile_test_ignore": {},
}
return &d
}
@ -158,11 +173,23 @@ func (d *DockerFileBuilder) BuildImage(imageRepo, gcsBucket, dockerfilesPath, do
"."},
additionalFlags...)...,
)
if d.includeDockerIgnore(dockerfile) {
if err := generateDockerIgnore(); err != nil {
return err
}
}
_, err := RunCommandWithoutTest(dockerCmd)
if err != nil {
return fmt.Errorf("Failed to build image %s with docker command \"%s\": %s", dockerImage, dockerCmd.Args, err)
}
if d.includeDockerIgnore(dockerfilesPath) {
if err := deleteDockerIgnore(); err != nil {
return err
}
}
contextFlag := "-c"
contextPath := buildContextPath
for _, d := range bucketContextTests {
@ -252,3 +279,29 @@ func (d *DockerFileBuilder) buildCachedImages(imageRepo, cacheRepo, dockerfilesP
}
return nil
}
func (d *DockerFileBuilder) includeDockerIgnore(dockerfile string) bool {
for i := range d.TestIgnoreDockerfiles {
if i == dockerfile {
return true
}
}
return false
}
func generateDockerIgnore() error {
f, err := os.Create(".dockerignore")
if err != nil {
return err
}
defer f.Close()
contents := strings.Join(filesToIgnore, "\n")
if _, err := f.Write([]byte(contents)); err != nil {
return err
}
return nil
}
func deleteDockerIgnore() error {
return os.Remove(".dockerignore")
}

View File

@ -28,6 +28,7 @@ type KanikoOptions struct {
CacheDir string
Destinations multiArg
BuildArgs multiArg
Ignore multiArg
InsecurePush bool
SkipTLSVerify bool
SingleSnapshot bool