Merge e1369aadf7 into 236ba5690e
				
					
				
			This commit is contained in:
		
						commit
						aa3ff604e1
					
				|  | @ -257,6 +257,8 @@ func addKanikoOptionsFlags() { | ||||||
| 	RootCmd.PersistentFlags().VarP(&opts.Compression, "compression", "", "Compression algorithm (gzip, zstd)") | 	RootCmd.PersistentFlags().VarP(&opts.Compression, "compression", "", "Compression algorithm (gzip, zstd)") | ||||||
| 	RootCmd.PersistentFlags().IntVarP(&opts.CompressionLevel, "compression-level", "", -1, "Compression level") | 	RootCmd.PersistentFlags().IntVarP(&opts.CompressionLevel, "compression-level", "", -1, "Compression level") | ||||||
| 	RootCmd.PersistentFlags().BoolVarP(&opts.Cache, "cache", "", false, "Use cache when building image") | 	RootCmd.PersistentFlags().BoolVarP(&opts.Cache, "cache", "", false, "Use cache when building image") | ||||||
|  | 	RootCmd.PersistentFlags().VarP(&opts.ExcludeBuildArgsFromCacheKey, "exclude-build-arg-from-cache-key", "", "This flag allows you to exclude ARG values from the cache key. Set it repeatedly for multiple values.") | ||||||
|  | 	RootCmd.PersistentFlags().VarP(&opts.ExcludeEnvsFromCacheKey, "exclude-env-from-cache-key", "", "This flag allows you to exclude ENV values from the cache key. Set it repeatedly for multiple values.") | ||||||
| 	RootCmd.PersistentFlags().BoolVarP(&opts.CompressedCaching, "compressed-caching", "", true, "Compress the cached layers. Decreases build time, but increases memory usage.") | 	RootCmd.PersistentFlags().BoolVarP(&opts.CompressedCaching, "compressed-caching", "", true, "Compress the cached layers. Decreases build time, but increases memory usage.") | ||||||
| 	RootCmd.PersistentFlags().BoolVarP(&opts.Cleanup, "cleanup", "", false, "Clean the filesystem at the end") | 	RootCmd.PersistentFlags().BoolVarP(&opts.Cleanup, "cleanup", "", false, "Clean the filesystem at the end") | ||||||
| 	RootCmd.PersistentFlags().DurationVarP(&opts.CacheTTL, "cache-ttl", "", time.Hour*336, "Cache timeout, requires value and unit of duration -> ex: 6h. Defaults to two weeks.") | 	RootCmd.PersistentFlags().DurationVarP(&opts.CacheTTL, "cache-ttl", "", time.Hour*336, "Cache timeout, requires value and unit of duration -> ex: 6h. Defaults to two weeks.") | ||||||
|  |  | ||||||
|  | @ -28,6 +28,9 @@ import ( | ||||||
| type CacheOptions struct { | type CacheOptions struct { | ||||||
| 	CacheDir string | 	CacheDir string | ||||||
| 	CacheTTL time.Duration | 	CacheTTL time.Duration | ||||||
|  | 
 | ||||||
|  | 	ExcludeBuildArgsFromCacheKey multiArg | ||||||
|  | 	ExcludeEnvsFromCacheKey      multiArg | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // RegistryOptions are all the options related to the registries, set by command line arguments.
 | // RegistryOptions are all the options related to the registries, set by command line arguments.
 | ||||||
|  |  | ||||||
|  | @ -199,20 +199,39 @@ func isOCILayout(path string) bool { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (s *stageBuilder) populateCompositeKey(command commands.DockerCommand, files []string, compositeKey CompositeCache, args *dockerfile.BuildArgs, env []string) (CompositeCache, error) { | func (s *stageBuilder) populateCompositeKey(command commands.DockerCommand, files []string, compositeKey CompositeCache, args *dockerfile.BuildArgs, env []string) (CompositeCache, error) { | ||||||
|  | 	if command.IsArgsEnvsRequiredInCache() { | ||||||
|  | 		filteredEnvs := []string{} | ||||||
|  | 		for _, e := range env { | ||||||
|  | 			envName := strings.SplitN(e, "=", 2)[0] | ||||||
|  | 			if s.opts.ExcludeEnvsFromCacheKey.Contains(envName) { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			filteredEnvs = append(filteredEnvs, e) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		// First replace all the environment variables or args in the command
 | 		// First replace all the environment variables or args in the command
 | ||||||
| 	replacementEnvs := args.ReplacementEnvs(env) | 		envsAndBuildArgs := args.ReplacementEnvs(filteredEnvs) | ||||||
| 	// The sort order of `replacementEnvs` is basically undefined, sort it
 | 
 | ||||||
|  | 		filteredEnvsAndBuildArgs := []string{} | ||||||
|  | 		for i, env := range envsAndBuildArgs { | ||||||
|  | 			envArgName := strings.SplitN(env, "=", 2)[0] | ||||||
|  | 			if s.opts.ExcludeBuildArgsFromCacheKey.Contains(envArgName) { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			filteredEnvsAndBuildArgs = append(filteredEnvs, envsAndBuildArgs[i]) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// The sort order of `filteredEnvs` is basically undefined, sort it
 | ||||||
| 		// so we can ensure a stable cache key.
 | 		// so we can ensure a stable cache key.
 | ||||||
| 	sort.Strings(replacementEnvs) | 		sort.Strings(filteredEnvsAndBuildArgs) | ||||||
|  | 
 | ||||||
|  | 		if len(filteredEnvsAndBuildArgs) > 0 { | ||||||
| 			// Use the special argument "|#" at the start of the args array. This will
 | 			// Use the special argument "|#" at the start of the args array. This will
 | ||||||
| 			// avoid conflicts with any RUN command since commands can not
 | 			// avoid conflicts with any RUN command since commands can not
 | ||||||
| 			// start with | (vertical bar). The "#" (number of build envs) is there to
 | 			// start with | (vertical bar). The "#" (number of build envs) is there to
 | ||||||
| 			// help ensure proper cache matches.
 | 			// help ensure proper cache matches.
 | ||||||
| 
 | 			compositeKey.AddKey(fmt.Sprintf("|%d", len(filteredEnvsAndBuildArgs))) | ||||||
| 	if command.IsArgsEnvsRequiredInCache() { | 			compositeKey.AddKey(filteredEnvsAndBuildArgs...) | ||||||
| 		if len(replacementEnvs) > 0 { |  | ||||||
| 			compositeKey.AddKey(fmt.Sprintf("|%d", len(replacementEnvs))) |  | ||||||
| 			compositeKey.AddKey(replacementEnvs...) |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -659,6 +659,8 @@ func Test_stageBuilder_populateCompositeKey(t *testing.T) { | ||||||
| 		cmd1                         stageContext | 		cmd1                         stageContext | ||||||
| 		cmd2                         stageContext | 		cmd2                         stageContext | ||||||
| 		shdEqual                     bool | 		shdEqual                     bool | ||||||
|  | 		excludeBuildArgsFromCacheKey []string | ||||||
|  | 		excludeEnvsFromCacheKey      []string | ||||||
| 	} | 	} | ||||||
| 	testCases := []testcase{ | 	testCases := []testcase{ | ||||||
| 		{ | 		{ | ||||||
|  | @ -744,6 +746,21 @@ func Test_stageBuilder_populateCompositeKey(t *testing.T) { | ||||||
| 				[]string{}, | 				[]string{}, | ||||||
| 			), | 			), | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			description: "cache key for same command [RUN] with a build arg values, with excludeBuildArgsFromCacheKey set", | ||||||
|  | 			cmd1: newStageContext( | ||||||
|  | 				"RUN echo $ARG > test", | ||||||
|  | 				map[string]string{"ARG": "foo"}, | ||||||
|  | 				[]string{}, | ||||||
|  | 			), | ||||||
|  | 			cmd2: newStageContext( | ||||||
|  | 				"RUN echo $ARG > test", | ||||||
|  | 				map[string]string{"ARG": "bar"}, | ||||||
|  | 				[]string{}, | ||||||
|  | 			), | ||||||
|  | 			shdEqual:                     true, | ||||||
|  | 			excludeBuildArgsFromCacheKey: []string{"ARG"}, | ||||||
|  | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			description: "cache key for same command [RUN] with different env values", | 			description: "cache key for same command [RUN] with different env values", | ||||||
| 			cmd1: newStageContext( | 			cmd1: newStageContext( | ||||||
|  | @ -798,6 +815,21 @@ func Test_stageBuilder_populateCompositeKey(t *testing.T) { | ||||||
| 			), | 			), | ||||||
| 			shdEqual: false, | 			shdEqual: false, | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			description: "cache key for command [RUN] with different env values, when excludeEnvsFromCacheKey is set", | ||||||
|  | 			cmd1: newStageContext( | ||||||
|  | 				"RUN echo ${APP_VERSION%.*} ${APP_VERSION%-*} > test", | ||||||
|  | 				map[string]string{"ARG": "foo"}, | ||||||
|  | 				[]string{"ENV=1"}, | ||||||
|  | 			), | ||||||
|  | 			cmd2: newStageContext( | ||||||
|  | 				"RUN echo ${APP_VERSION%.*} ${APP_VERSION%-*} > test", | ||||||
|  | 				map[string]string{"ARG": "foo"}, | ||||||
|  | 				[]string{"ENV=2"}, | ||||||
|  | 			), | ||||||
|  | 			shdEqual:                true, | ||||||
|  | 			excludeEnvsFromCacheKey: []string{"ENV"}, | ||||||
|  | 		}, | ||||||
| 		func() testcase { | 		func() testcase { | ||||||
| 			dir, files := tempDirAndFile(t) | 			dir, files := tempDirAndFile(t) | ||||||
| 			file := files[0] | 			file := files[0] | ||||||
|  | @ -867,7 +899,15 @@ func Test_stageBuilder_populateCompositeKey(t *testing.T) { | ||||||
| 	} | 	} | ||||||
| 	for _, tc := range testCases { | 	for _, tc := range testCases { | ||||||
| 		t.Run(tc.description, func(t *testing.T) { | 		t.Run(tc.description, func(t *testing.T) { | ||||||
| 			sb := &stageBuilder{fileContext: util.FileContext{Root: "workspace"}} | 			sb := &stageBuilder{ | ||||||
|  | 				fileContext: util.FileContext{Root: "workspace"}, | ||||||
|  | 				opts: &config.KanikoOptions{ | ||||||
|  | 					CacheOptions: config.CacheOptions{ | ||||||
|  | 						ExcludeBuildArgsFromCacheKey: tc.excludeBuildArgsFromCacheKey, | ||||||
|  | 						ExcludeEnvsFromCacheKey:      tc.excludeEnvsFromCacheKey, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			} | ||||||
| 			ck := CompositeCache{} | 			ck := CompositeCache{} | ||||||
| 
 | 
 | ||||||
| 			instructions1, err := dockerfile.ParseCommands([]string{tc.cmd1.command.String()}) | 			instructions1, err := dockerfile.ParseCommands([]string{tc.cmd1.command.String()}) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue