github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/gcb/kaniko_test.go (about) 1 /* 2 Copyright 2019 The Skaffold Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package gcb 18 19 import ( 20 "context" 21 "testing" 22 23 "google.golang.org/api/cloudbuild/v1" 24 kv1 "k8s.io/api/core/v1" 25 26 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/kaniko" 27 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/config" 28 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" 29 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph" 30 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform" 31 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" 32 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" 33 "github.com/GoogleContainerTools/skaffold/testutil" 34 ) 35 36 func TestKanikoBuildSpec(t *testing.T) { 37 tests := []struct { 38 description string 39 artifact *latest.KanikoArtifact 40 expectedArgs []string 41 expectedEnv []string 42 }{ 43 { 44 description: "simple build", 45 artifact: &latest.KanikoArtifact{ 46 DockerfilePath: "Dockerfile", 47 }, 48 expectedArgs: []string{}, 49 }, 50 { 51 description: "with BuildArgs", 52 artifact: &latest.KanikoArtifact{ 53 DockerfilePath: "Dockerfile", 54 BuildArgs: map[string]*string{ 55 "arg1": util.StringPtr("value1"), 56 "arg2": nil, 57 }, 58 }, 59 expectedArgs: []string{ 60 kaniko.BuildArgsFlag, "arg1=value1", 61 kaniko.BuildArgsFlag, "arg2", 62 }, 63 }, 64 { 65 description: "with Env", 66 artifact: &latest.KanikoArtifact{ 67 DockerfilePath: "Dockerfile", 68 Env: []kv1.EnvVar{{Name: "KEY1", Value: "VALUE1"}, {Name: "KEY2", Value: "VALUE2"}}, 69 }, 70 expectedEnv: []string{"KEY1=VALUE1", "KEY2=VALUE2"}, 71 }, 72 { 73 description: "with Cache", 74 artifact: &latest.KanikoArtifact{ 75 DockerfilePath: "Dockerfile", 76 Cache: &latest.KanikoCache{}, 77 }, 78 expectedArgs: []string{ 79 kaniko.CacheFlag, 80 }, 81 }, 82 { 83 description: "with Cache Copy Layers", 84 artifact: &latest.KanikoArtifact{ 85 DockerfilePath: "Dockerfile", 86 Cache: &latest.KanikoCache{CacheCopyLayers: true}, 87 }, 88 expectedArgs: []string{ 89 kaniko.CacheFlag, 90 kaniko.CacheCopyLayersFlag, 91 }, 92 }, 93 { 94 description: "with Cleanup", 95 artifact: &latest.KanikoArtifact{ 96 DockerfilePath: "Dockerfile", 97 Cleanup: true, 98 }, 99 expectedArgs: []string{ 100 kaniko.CleanupFlag, 101 }, 102 }, 103 { 104 description: "with DigestFile", 105 artifact: &latest.KanikoArtifact{ 106 DockerfilePath: "Dockerfile", 107 DigestFile: "/tmp/digest", 108 }, 109 expectedArgs: []string{ 110 kaniko.DigestFileFlag, "/tmp/digest", 111 }, 112 }, 113 { 114 description: "with Force", 115 artifact: &latest.KanikoArtifact{ 116 DockerfilePath: "Dockerfile", 117 Force: true, 118 }, 119 expectedArgs: []string{ 120 kaniko.ForceFlag, 121 }, 122 }, 123 { 124 description: "with ImageFSExtractRetry", 125 artifact: &latest.KanikoArtifact{ 126 DockerfilePath: "Dockerfile", 127 ImageFSExtractRetry: "5", 128 }, 129 expectedArgs: []string{ 130 "--image-fs-extract-retry", "5", 131 }, 132 }, 133 { 134 description: "with ImageNameWithDigestFile", 135 artifact: &latest.KanikoArtifact{ 136 DockerfilePath: "Dockerfile", 137 ImageNameWithDigestFile: "/tmp/imageName", 138 }, 139 expectedArgs: []string{ 140 kaniko.ImageNameWithDigestFileFlag, "/tmp/imageName", 141 }, 142 }, 143 { 144 description: "with Insecure", 145 artifact: &latest.KanikoArtifact{ 146 DockerfilePath: "Dockerfile", 147 Insecure: true, 148 }, 149 expectedArgs: []string{ 150 kaniko.InsecureFlag, 151 }, 152 }, 153 { 154 description: "with InsecurePull", 155 artifact: &latest.KanikoArtifact{ 156 DockerfilePath: "Dockerfile", 157 InsecurePull: true, 158 }, 159 expectedArgs: []string{ 160 kaniko.InsecurePullFlag, 161 }, 162 }, 163 { 164 description: "with InsecureRegistry", 165 artifact: &latest.KanikoArtifact{ 166 DockerfilePath: "Dockerfile", 167 InsecureRegistry: []string{ 168 "s1.registry.url:5000", 169 "s2.registry.url:5000", 170 }, 171 }, 172 expectedArgs: []string{ 173 kaniko.InsecureRegistryFlag, "s1.registry.url:5000", 174 kaniko.InsecureRegistryFlag, "s2.registry.url:5000", 175 }, 176 }, 177 { 178 description: "with LogFormat", 179 artifact: &latest.KanikoArtifact{ 180 DockerfilePath: "Dockerfile", 181 LogFormat: "json", 182 }, 183 expectedArgs: []string{ 184 kaniko.LogFormatFlag, "json", 185 }, 186 }, 187 { 188 description: "with LogTimestamp", 189 artifact: &latest.KanikoArtifact{ 190 DockerfilePath: "Dockerfile", 191 LogTimestamp: true, 192 }, 193 expectedArgs: []string{ 194 kaniko.LogTimestampFlag, 195 }, 196 }, 197 { 198 description: "with NoPush", 199 artifact: &latest.KanikoArtifact{ 200 DockerfilePath: "Dockerfile", 201 NoPush: true, 202 }, 203 expectedArgs: []string{ 204 kaniko.NoPushFlag, 205 }, 206 }, 207 { 208 description: "with OCILayoutPath", 209 artifact: &latest.KanikoArtifact{ 210 DockerfilePath: "Dockerfile", 211 OCILayoutPath: "/tmp/builtImage", 212 }, 213 expectedArgs: []string{ 214 kaniko.OCILayoutFlag, "/tmp/builtImage", 215 }, 216 }, 217 { 218 description: "with RegistryCertificate", 219 artifact: &latest.KanikoArtifact{ 220 DockerfilePath: "Dockerfile", 221 RegistryCertificate: map[string]*string{ 222 "s1.registry.url": util.StringPtr("/etc/certs/certificate1.cert"), 223 "s2.registry.url": util.StringPtr("/etc/certs/certificate2.cert"), 224 }, 225 }, 226 expectedArgs: []string{ 227 kaniko.RegistryCertificateFlag, "s1.registry.url=/etc/certs/certificate1.cert", 228 kaniko.RegistryCertificateFlag, "s2.registry.url=/etc/certs/certificate2.cert", 229 }, 230 }, 231 { 232 description: "with RegistryMirror", 233 artifact: &latest.KanikoArtifact{ 234 DockerfilePath: "Dockerfile", 235 RegistryMirror: "mirror.gcr.io", 236 }, 237 expectedArgs: []string{ 238 kaniko.RegistryMirrorFlag, "mirror.gcr.io", 239 }, 240 }, 241 { 242 description: "with Reproducible", 243 artifact: &latest.KanikoArtifact{ 244 DockerfilePath: "Dockerfile", 245 Reproducible: true, 246 }, 247 expectedArgs: []string{ 248 kaniko.ReproducibleFlag, 249 }, 250 }, 251 { 252 description: "with SingleSnapshot", 253 artifact: &latest.KanikoArtifact{ 254 DockerfilePath: "Dockerfile", 255 SingleSnapshot: true, 256 }, 257 expectedArgs: []string{ 258 kaniko.SingleSnapshotFlag, 259 }, 260 }, 261 { 262 description: "with SkipTLS", 263 artifact: &latest.KanikoArtifact{ 264 DockerfilePath: "Dockerfile", 265 SkipTLS: true, 266 }, 267 expectedArgs: []string{ 268 kaniko.SkipTLSFlag, 269 kaniko.SkipTLSVerifyRegistryFlag, "gcr.io", 270 }, 271 }, 272 { 273 description: "with SkipTLSVerifyPull", 274 artifact: &latest.KanikoArtifact{ 275 DockerfilePath: "Dockerfile", 276 SkipTLSVerifyPull: true, 277 }, 278 expectedArgs: []string{ 279 kaniko.SkipTLSVerifyPullFlag, 280 }, 281 }, 282 { 283 description: "with SkipTLSVerifyRegistry", 284 artifact: &latest.KanikoArtifact{ 285 DockerfilePath: "Dockerfile", 286 SkipTLSVerifyRegistry: []string{ 287 "s1.registry.url:5000", 288 "s2.registry.url:5000", 289 }, 290 }, 291 expectedArgs: []string{ 292 kaniko.SkipTLSVerifyRegistryFlag, "s1.registry.url:5000", 293 kaniko.SkipTLSVerifyRegistryFlag, "s2.registry.url:5000", 294 }, 295 }, 296 { 297 description: "with SkipUnusedStages", 298 artifact: &latest.KanikoArtifact{ 299 DockerfilePath: "Dockerfile", 300 SkipUnusedStages: true, 301 }, 302 expectedArgs: []string{ 303 kaniko.SkipUnusedStagesFlag, 304 }, 305 }, 306 { 307 description: "with Target", 308 artifact: &latest.KanikoArtifact{ 309 DockerfilePath: "Dockerfile", 310 Target: "builder", 311 }, 312 expectedArgs: []string{ 313 kaniko.TargetFlag, "builder", 314 }, 315 }, 316 { 317 description: "with SnapshotMode", 318 artifact: &latest.KanikoArtifact{ 319 DockerfilePath: "Dockerfile", 320 SnapshotMode: "redo", 321 }, 322 expectedArgs: []string{ 323 "--snapshotMode", "redo", 324 }, 325 }, 326 { 327 description: "with PushRetry", 328 artifact: &latest.KanikoArtifact{ 329 DockerfilePath: "Dockerfile", 330 PushRetry: "9", 331 }, 332 expectedArgs: []string{ 333 "--push-retry", "9", 334 }, 335 }, 336 { 337 description: "with TarPath", 338 artifact: &latest.KanikoArtifact{ 339 DockerfilePath: "Dockerfile", 340 TarPath: "/workspace/tars", 341 }, 342 expectedArgs: []string{ 343 kaniko.TarPathFlag, "/workspace/tars", 344 }, 345 }, 346 { 347 description: "with UseNewRun", 348 artifact: &latest.KanikoArtifact{ 349 DockerfilePath: "Dockerfile", 350 UseNewRun: true, 351 }, 352 expectedArgs: []string{ 353 kaniko.UseNewRunFlag, 354 }, 355 }, 356 { 357 description: "with Verbosity", 358 artifact: &latest.KanikoArtifact{ 359 DockerfilePath: "Dockerfile", 360 Verbosity: "trace", 361 }, 362 expectedArgs: []string{ 363 kaniko.VerbosityFlag, "trace", 364 }, 365 }, 366 { 367 description: "with WhitelistVarRun", 368 artifact: &latest.KanikoArtifact{ 369 DockerfilePath: "Dockerfile", 370 WhitelistVarRun: true, 371 }, 372 expectedArgs: []string{ 373 kaniko.WhitelistVarRunFlag, 374 }, 375 }, 376 { 377 description: "with WhitelistVarRun", 378 artifact: &latest.KanikoArtifact{ 379 DockerfilePath: "Dockerfile", 380 WhitelistVarRun: true, 381 }, 382 expectedArgs: []string{ 383 kaniko.WhitelistVarRunFlag, 384 }, 385 }, 386 { 387 description: "with Labels", 388 artifact: &latest.KanikoArtifact{ 389 DockerfilePath: "Dockerfile", 390 Label: map[string]*string{ 391 "label1": util.StringPtr("value1"), 392 "label2": nil, 393 }, 394 }, 395 expectedArgs: []string{ 396 kaniko.LabelFlag, "label1=value1", 397 kaniko.LabelFlag, "label2", 398 }, 399 }, 400 } 401 store := mockArtifactStore{ 402 "img2": "img2:tag", 403 "img3": "img3:tag", 404 } 405 builder := NewBuilder(&mockBuilderContext{artifactStore: store}, &latest.GoogleCloudBuild{ 406 KanikoImage: "gcr.io/kaniko-project/executor", 407 DiskSizeGb: 100, 408 MachineType: "n1-standard-1", 409 Timeout: "10m", 410 }) 411 412 defaultExpectedArgs := []string{ 413 "--destination", "gcr.io/nginx", 414 "--dockerfile", "Dockerfile", 415 } 416 417 for _, test := range tests { 418 testutil.Run(t, test.description, func(t *testutil.T) { 419 artifact := &latest.Artifact{ 420 ImageName: "img1", 421 ArtifactType: latest.ArtifactType{ 422 KanikoArtifact: test.artifact, 423 }, 424 Dependencies: []*latest.ArtifactDependency{ 425 {ImageName: "img2", Alias: "IMG2"}, 426 {ImageName: "img3", Alias: "IMG3"}, 427 }, 428 } 429 430 imageArgs := []string{kaniko.BuildArgsFlag, "IMG2=img2:tag", kaniko.BuildArgsFlag, "IMG3=img3:tag"} 431 432 t.Override(&docker.EvalBuildArgs, func(_ config.RunMode, _ string, _ string, args map[string]*string, extra map[string]*string) (map[string]*string, error) { 433 m := make(map[string]*string) 434 for k, v := range args { 435 m[k] = v 436 } 437 for k, v := range extra { 438 m[k] = v 439 } 440 return m, nil 441 }) 442 desc, err := builder.buildSpec(context.Background(), artifact, "gcr.io/nginx", platform.Matcher{}, "bucket", "object") 443 444 expected := cloudbuild.Build{ 445 LogsBucket: "bucket", 446 Source: &cloudbuild.Source{ 447 StorageSource: &cloudbuild.StorageSource{ 448 Bucket: "bucket", 449 Object: "object", 450 }, 451 }, 452 Steps: []*cloudbuild.BuildStep{{ 453 Name: "gcr.io/kaniko-project/executor", 454 Args: append(append(defaultExpectedArgs, imageArgs...), test.expectedArgs...), 455 Env: test.expectedEnv, 456 }}, 457 Options: &cloudbuild.BuildOptions{ 458 DiskSizeGb: 100, 459 MachineType: "n1-standard-1", 460 }, 461 Timeout: "10m", 462 } 463 464 t.CheckNoError(err) 465 t.CheckDeepEqual(expected, desc) 466 }) 467 } 468 } 469 470 type mockArtifactStore map[string]string 471 472 func (m mockArtifactStore) GetImageTag(imageName string) (string, bool) { return m[imageName], true } 473 func (m mockArtifactStore) Record(a *latest.Artifact, tag string) { m[a.ImageName] = tag } 474 func (m mockArtifactStore) GetArtifacts([]*latest.Artifact) ([]graph.Artifact, error) { 475 return nil, nil 476 }