gopkg.in/openshift/source-to-image.v1@v1.2.0/test/integration/dockerfile/dockerfile_test.go (about) 1 // +build integration 2 3 package dockerfile 4 5 import ( 6 "bytes" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "regexp" 11 "strings" 12 "testing" 13 14 "github.com/docker/docker/builder/dockerfile/parser" 15 "github.com/openshift/source-to-image/pkg/api" 16 "github.com/openshift/source-to-image/pkg/build/strategies" 17 "github.com/openshift/source-to-image/pkg/scm/git" 18 ) 19 20 func TestDockerfileBuild(t *testing.T) { 21 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 22 if err != nil { 23 t.Errorf("Unable to create temporary directory: %v", err) 24 } 25 defer os.RemoveAll(tempdir) 26 27 config := &api.Config{ 28 BuilderImage: "docker.io/centos/nodejs-8-centos7", 29 AssembleUser: "", 30 ImageWorkDir: "", 31 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 32 ScriptsURL: "", 33 Injections: api.VolumeList{}, 34 Destination: "", 35 36 Environment: api.EnvironmentList{}, 37 Labels: map[string]string{}, 38 39 AsDockerfile: tempdir + string(os.PathSeparator) + "MyDockerfile", 40 } 41 expected := []string{ 42 "(?m)^FROM docker.io/centos/nodejs-8-centos7", 43 "\"io.openshift.s2i.build.commit.date\"", 44 "\"io.openshift.s2i.build.commit.id\"", 45 "\"io.openshift.s2i.build.commit.ref\"", 46 "\"io.openshift.s2i.build.commit.message\"", 47 "\"io.openshift.s2i.build.source-location\"", 48 "\"io.openshift.s2i.build.image\"=\"docker.io/centos/nodejs-8-centos7\"", 49 "\"io.openshift.s2i.build.commit.author\"", 50 "(?m)^COPY upload/src /tmp/src", 51 "(?m)^RUN chown -R 1001:0.* /tmp/src", 52 // Ensure we are using the default image user when running assemble 53 "(?m)^USER 1001\n.+\n.+\nRUN /usr/libexec/s2i/assemble", 54 "(?m)^CMD /usr/libexec/s2i/run", 55 } 56 expectedFiles := []string{ 57 filepath.Join(tempdir, "upload/src/server.js"), 58 filepath.Join(tempdir, "MyDockerfile"), 59 } 60 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 61 } 62 63 func TestDockerfileBuildDefaultDockerfile(t *testing.T) { 64 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 65 if err != nil { 66 t.Errorf("Unable to create temporary directory: %v", err) 67 } 68 defer os.RemoveAll(tempdir) 69 70 config := &api.Config{ 71 BuilderImage: "docker.io/centos/nodejs-8-centos7", 72 AssembleUser: "", 73 ImageWorkDir: "", 74 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 75 ScriptsURL: "", 76 Injections: api.VolumeList{}, 77 Destination: "", 78 79 Environment: api.EnvironmentList{}, 80 Labels: map[string]string{}, 81 82 AsDockerfile: tempdir + string(os.PathSeparator), 83 } 84 expected := []string{ 85 "(?m)^FROM docker.io/centos/nodejs-8-centos7", 86 "\"io.openshift.s2i.build.commit.date\"", 87 "\"io.openshift.s2i.build.commit.id\"", 88 "\"io.openshift.s2i.build.commit.ref\"", 89 "\"io.openshift.s2i.build.commit.message\"", 90 "\"io.openshift.s2i.build.source-location\"", 91 "\"io.openshift.s2i.build.image\"=\"docker.io/centos/nodejs-8-centos7\"", 92 "\"io.openshift.s2i.build.commit.author\"", 93 "(?m)^COPY upload/src /tmp/src", 94 "(?m)^RUN chown -R 1001:0.* /tmp/src", 95 "(?m)^RUN /usr/libexec/s2i/assemble", 96 "(?m)^CMD /usr/libexec/s2i/run", 97 } 98 expectedFiles := []string{ 99 filepath.Join(tempdir, "upload/src/server.js"), 100 filepath.Join(tempdir, "Dockerfile"), 101 } 102 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 103 } 104 105 func TestDockerfileBuildEnv(t *testing.T) { 106 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 107 if err != nil { 108 t.Errorf("Unable to create temporary directory: %v", err) 109 } 110 defer os.RemoveAll(tempdir) 111 112 config := &api.Config{ 113 BuilderImage: "docker.io/centos/nodejs-8-centos7", 114 AssembleUser: "", 115 ImageWorkDir: "", 116 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 117 ScriptsURL: "", 118 Injections: api.VolumeList{}, 119 Destination: "", 120 121 Environment: api.EnvironmentList{ 122 { 123 Name: "key1", 124 Value: "value1", 125 }, 126 { 127 Name: "key2", 128 Value: "value2", 129 }, 130 }, 131 Labels: map[string]string{}, 132 133 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 134 } 135 136 expected := []string{ 137 "key1=\"value1\"", 138 "key2=\"value2\"", 139 } 140 runDockerfileTest(t, config, expected, nil, nil, false) 141 } 142 143 func TestDockerfileBuildLabels(t *testing.T) { 144 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 145 if err != nil { 146 t.Errorf("Unable to create temporary directory: %v", err) 147 } 148 defer os.RemoveAll(tempdir) 149 150 config := &api.Config{ 151 BuilderImage: "docker.io/centos/nodejs-8-centos7", 152 AssembleUser: "", 153 ImageWorkDir: "", 154 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 155 ScriptsURL: "", 156 Injections: api.VolumeList{}, 157 Destination: "", 158 159 Environment: api.EnvironmentList{}, 160 Labels: map[string]string{"label1": "value1", 161 "label2": "value2", 162 "io.openshift.s2i.build.commit.author": "shadowman"}, 163 164 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 165 } 166 expected := []string{ 167 "\"io.openshift.s2i.build.commit.date\"", 168 "\"io.openshift.s2i.build.commit.id\"", 169 "\"io.openshift.s2i.build.commit.ref\"", 170 "\"io.openshift.s2i.build.commit.message\"", 171 "\"io.openshift.s2i.build.source-location\"", 172 "\"io.openshift.s2i.build.image\"=\"docker.io/centos/nodejs-8-centos7\"", 173 "\"io.openshift.s2i.build.commit.author\"=\"shadowman\"", 174 "\"label1\"=\"value1\"", 175 "\"label2\"=\"value2\"", 176 } 177 runDockerfileTest(t, config, expected, nil, nil, false) 178 } 179 180 func TestDockerfileBuildInjections(t *testing.T) { 181 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 182 if err != nil { 183 t.Errorf("Unable to create temporary directory: %v", err) 184 } 185 defer os.RemoveAll(tempdir) 186 187 injection1 := filepath.Join(tempdir, "injection1") 188 err = os.Mkdir(injection1, 0777) 189 if err != nil { 190 t.Errorf("Unable to create injection dir: %v", err) 191 } 192 193 for i := 0; i < 3; i++ { 194 _, err = ioutil.TempFile(injection1, "injectfile-") 195 if err != nil { 196 t.Errorf("Unable to create injection file: %v", err) 197 } 198 } 199 200 injection2 := filepath.Join(tempdir, "injection2") 201 err = os.Mkdir(injection2, 0777) 202 if err != nil { 203 t.Errorf("Unable to create injection dir: %v", err) 204 } 205 _, err = ioutil.TempFile(injection2, "injectfile-2") 206 if err != nil { 207 t.Errorf("Unable to create injection file: %v", err) 208 } 209 210 config := &api.Config{ 211 BuilderImage: "docker.io/centos/nodejs-8-centos7", 212 AssembleUser: "", 213 ImageWorkDir: "/workdir", 214 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 215 ScriptsURL: "", 216 Injections: api.VolumeList{ 217 { 218 Source: injection1, 219 Destination: "injection1", 220 Keep: false, 221 }, 222 { 223 Source: injection2, 224 Destination: "/destination/injection2", 225 Keep: true, 226 }, 227 }, 228 Destination: "", 229 230 Environment: api.EnvironmentList{}, 231 Labels: map[string]string{}, 232 233 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 234 } 235 236 // strip the C: from windows paths because it's not valid in the middle of a path 237 // like upload/injections/C:/tempdir/injection1 238 trimmedInjection1 := filepath.ToSlash(strings.TrimPrefix(injection1, filepath.VolumeName(injection1))) 239 trimmedInjection2 := filepath.ToSlash(strings.TrimPrefix(injection2, filepath.VolumeName(injection2))) 240 241 expected := []string{ 242 "(?m)^COPY upload/injections" + trimmedInjection1 + " /workdir/injection1", 243 "(?m)^RUN chown -R 1001:0.* /workdir/injection1", 244 "(?m)^COPY upload/injections" + trimmedInjection2 + " /destination/injection2", 245 "(?m)^RUN chown -R 1001:0.* /destination/injection2", 246 "(?m)^RUN rm /workdir/injection1/injectfile-", 247 " rm /workdir/injection1/injectfile-", 248 } 249 notExpected := []string{ 250 "rm -rf /destination/injection2", 251 } 252 expectedFiles := []string{ 253 filepath.Join(tempdir, "upload/src/server.js"), 254 filepath.Join(tempdir, "upload/injections"+trimmedInjection1), 255 filepath.Join(tempdir, "upload/injections"+trimmedInjection2), 256 } 257 runDockerfileTest(t, config, expected, notExpected, expectedFiles, false) 258 } 259 260 func TestDockerfileBuildScriptsURLAssemble(t *testing.T) { 261 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 262 if err != nil { 263 t.Errorf("Unable to create temporary directory: %v", err) 264 } 265 defer os.RemoveAll(tempdir) 266 267 assemble := filepath.Join(tempdir, "assemble") 268 _, err = os.OpenFile(assemble, os.O_RDONLY|os.O_CREATE, 0666) 269 if err != nil { 270 t.Errorf("Unable to create assemble file: %v", err) 271 } 272 273 config := &api.Config{ 274 BuilderImage: "docker.io/centos/nodejs-8-centos7", 275 AssembleUser: "", 276 ImageWorkDir: "", 277 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 278 ScriptsURL: "file://" + filepath.ToSlash(tempdir), 279 Injections: api.VolumeList{}, 280 Destination: "/destination", 281 282 Environment: api.EnvironmentList{}, 283 Labels: map[string]string{}, 284 285 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 286 } 287 expected := []string{ 288 "(?m)^COPY upload/scripts /destination/scripts", 289 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 290 "(?m)^RUN /destination/scripts/assemble", 291 "(?m)^CMD /usr/libexec/s2i/run", 292 } 293 expectedFiles := []string{ 294 filepath.Join(tempdir, "upload/src/server.js"), 295 filepath.Join(tempdir, "upload/scripts/assemble"), 296 } 297 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 298 } 299 300 func TestDockerfileBuildScriptsURLRun(t *testing.T) { 301 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 302 if err != nil { 303 t.Errorf("Unable to create temporary directory: %v", err) 304 } 305 defer os.RemoveAll(tempdir) 306 307 run := filepath.Join(tempdir, "run") 308 _, err = os.OpenFile(run, os.O_RDONLY|os.O_CREATE, 0666) 309 if err != nil { 310 t.Errorf("Unable to create run file: %v", err) 311 } 312 313 config := &api.Config{ 314 BuilderImage: "docker.io/centos/nodejs-8-centos7", 315 AssembleUser: "", 316 ImageWorkDir: "", 317 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 318 ScriptsURL: "file://" + filepath.ToSlash(tempdir), 319 Injections: api.VolumeList{}, 320 Destination: "/destination", 321 322 Environment: api.EnvironmentList{}, 323 Labels: map[string]string{}, 324 325 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 326 } 327 expected := []string{ 328 "(?m)^COPY upload/scripts /destination/scripts", 329 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 330 "(?m)^RUN /usr/libexec/s2i/assemble", 331 "(?m)^CMD /destination/scripts/run", 332 } 333 expectedFiles := []string{ 334 filepath.Join(tempdir, "upload/src/server.js"), 335 filepath.Join(tempdir, "upload/scripts/run"), 336 } 337 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 338 } 339 340 func TestDockerfileBuildScriptsURLNone(t *testing.T) { 341 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 342 if err != nil { 343 t.Errorf("Unable to create temporary directory: %v", err) 344 } 345 defer os.RemoveAll(tempdir) 346 347 config := &api.Config{ 348 BuilderImage: "docker.io/centos/nodejs-8-centos7", 349 AssembleUser: "", 350 ImageWorkDir: "", 351 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 352 ScriptsURL: "file://" + filepath.ToSlash(tempdir), 353 Injections: api.VolumeList{}, 354 Destination: "/destination", 355 356 Environment: api.EnvironmentList{}, 357 Labels: map[string]string{}, 358 359 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 360 } 361 runDockerfileTest(t, config, nil, nil, nil, true) 362 } 363 364 func TestDockerfileBuildSourceScriptsAssemble(t *testing.T) { 365 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 366 if err != nil { 367 t.Errorf("Unable to create temporary directory: %v", err) 368 } 369 defer os.RemoveAll(tempdir) 370 371 sourcecode := filepath.Join(tempdir, "sourcecode") 372 sourcescripts := filepath.Join(sourcecode, ".s2i", "bin") 373 err = os.MkdirAll(sourcescripts, 0777) 374 if err != nil { 375 t.Errorf("Unable to create injection dir: %v", err) 376 } 377 378 assemble := filepath.Join(sourcescripts, "assemble") 379 _, err = os.OpenFile(assemble, os.O_RDONLY|os.O_CREATE, 0666) 380 if err != nil { 381 t.Errorf("Unable to create assemble file: %v", err) 382 } 383 384 config := &api.Config{ 385 BuilderImage: "docker.io/centos/nodejs-8-centos7", 386 AssembleUser: "", 387 ImageWorkDir: "", 388 Source: git.MustParse("file:///" + filepath.ToSlash(sourcecode)), 389 ForceCopy: true, 390 ScriptsURL: "", 391 Injections: api.VolumeList{}, 392 Destination: "/destination", 393 394 Environment: api.EnvironmentList{}, 395 Labels: map[string]string{}, 396 397 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 398 } 399 expected := []string{ 400 "(?m)^COPY upload/scripts /destination/scripts", 401 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 402 "(?m)^RUN /destination/scripts/assemble", 403 "(?m)^CMD /usr/libexec/s2i/run", 404 } 405 expectedFiles := []string{ 406 filepath.Join(tempdir, "upload/scripts/assemble"), 407 } 408 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 409 } 410 411 func TestDockerfileBuildSourceScriptsRun(t *testing.T) { 412 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 413 if err != nil { 414 t.Errorf("Unable to create temporary directory: %v", err) 415 } 416 defer os.RemoveAll(tempdir) 417 418 sourcecode := filepath.Join(tempdir, "sourcecode") 419 sourcescripts := filepath.Join(sourcecode, ".s2i", "bin") 420 err = os.MkdirAll(sourcescripts, 0777) 421 if err != nil { 422 t.Errorf("Unable to create injection dir: %v", err) 423 } 424 425 run := filepath.Join(sourcescripts, "run") 426 _, err = os.OpenFile(run, os.O_RDONLY|os.O_CREATE, 0666) 427 if err != nil { 428 t.Errorf("Unable to create run file: %v", err) 429 } 430 431 config := &api.Config{ 432 BuilderImage: "docker.io/centos/nodejs-8-centos7", 433 AssembleUser: "", 434 ImageWorkDir: "", 435 Source: git.MustParse("file:///" + filepath.ToSlash(sourcecode)), 436 ForceCopy: true, 437 ScriptsURL: "", 438 Injections: api.VolumeList{}, 439 Destination: "/destination", 440 441 Environment: api.EnvironmentList{}, 442 Labels: map[string]string{}, 443 444 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 445 } 446 expected := []string{ 447 "(?m)^COPY upload/scripts /destination/scripts", 448 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 449 "(?m)^RUN /usr/libexec/s2i/assemble", 450 "(?m)^CMD /destination/scripts/run", 451 } 452 expectedFiles := []string{ 453 filepath.Join(tempdir, "upload/scripts/run"), 454 } 455 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 456 } 457 458 // TestDockerfileBuildScriptsURLImage tests the behavior if the ScriptsURL 459 // is set to an image:// URL. In this case we blind trust that the image 460 // contains all of the s2i scripts at the given directory, regardless 461 // of what is contained in the source. 462 func TestDockerfileBuildScriptsURLImage(t *testing.T) { 463 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 464 if err != nil { 465 t.Errorf("Unable to create temporary directory: %v", err) 466 } 467 defer os.RemoveAll(tempdir) 468 469 sourcecode := filepath.Join(tempdir, "sourcecode") 470 sourcescripts := filepath.Join(sourcecode, ".s2i", "bin") 471 err = os.MkdirAll(sourcescripts, 0777) 472 if err != nil { 473 t.Errorf("Unable to create injection dir: %v", err) 474 } 475 476 assemble := filepath.Join(sourcescripts, "assemble") 477 _, err = os.OpenFile(assemble, os.O_RDONLY|os.O_CREATE, 0666) 478 if err != nil { 479 t.Errorf("Unable to create assemble file: %v", err) 480 } 481 482 config := &api.Config{ 483 BuilderImage: "docker.io/centos/nodejs-8-centos7", 484 AssembleUser: "", 485 ImageWorkDir: "", 486 Source: git.MustParse("file:///" + filepath.ToSlash(sourcecode)), 487 ForceCopy: true, 488 ScriptsURL: "image:///usr/custom/s2i", 489 Injections: api.VolumeList{}, 490 Destination: "/destination", 491 492 Environment: api.EnvironmentList{}, 493 Labels: map[string]string{}, 494 495 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 496 } 497 expected := []string{ 498 "(?m)^RUN /usr/custom/s2i/assemble", 499 "(?m)^CMD /usr/custom/s2i/run", 500 } 501 notExpected := []string{ 502 "(?m)^COPY upload/scripts /destination/scripts", 503 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 504 "(?m)^RUN /destination/scripts/assemble", 505 } 506 runDockerfileTest(t, config, expected, notExpected, nil, false) 507 } 508 509 func TestDockerfileBuildImageScriptsURLAssemble(t *testing.T) { 510 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 511 if err != nil { 512 t.Errorf("Unable to create temporary directory: %v", err) 513 } 514 defer os.RemoveAll(tempdir) 515 516 assemble := filepath.Join(tempdir, "assemble") 517 _, err = os.OpenFile(assemble, os.O_RDONLY|os.O_CREATE, 0666) 518 if err != nil { 519 t.Errorf("Unable to create assemble file: %v", err) 520 } 521 522 config := &api.Config{ 523 BuilderImage: "docker.io/centos/nodejs-8-centos7", 524 AssembleUser: "", 525 ImageWorkDir: "", 526 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 527 ImageScriptsURL: "file://" + filepath.ToSlash(tempdir), 528 Injections: api.VolumeList{}, 529 Destination: "/destination", 530 531 Environment: api.EnvironmentList{}, 532 Labels: map[string]string{}, 533 534 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 535 } 536 expected := []string{ 537 "(?m)^COPY upload/scripts /destination/scripts", 538 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 539 "(?m)^RUN /destination/scripts/assemble", 540 "(?m)^CMD /usr/libexec/s2i/run", 541 } 542 expectedFiles := []string{ 543 filepath.Join(tempdir, "upload/src/server.js"), 544 filepath.Join(tempdir, "upload/scripts/assemble"), 545 } 546 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 547 } 548 549 func TestDockerfileBuildImageScriptsURLRun(t *testing.T) { 550 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 551 if err != nil { 552 t.Errorf("Unable to create temporary directory: %v", err) 553 } 554 defer os.RemoveAll(tempdir) 555 556 run := filepath.Join(tempdir, "run") 557 _, err = os.OpenFile(run, os.O_RDONLY|os.O_CREATE, 0666) 558 if err != nil { 559 t.Errorf("Unable to create run file: %v", err) 560 } 561 562 config := &api.Config{ 563 BuilderImage: "docker.io/centos/nodejs-8-centos7", 564 AssembleUser: "", 565 ImageWorkDir: "", 566 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 567 ImageScriptsURL: "file://" + filepath.ToSlash(tempdir), 568 Injections: api.VolumeList{}, 569 Destination: "/destination", 570 571 Environment: api.EnvironmentList{}, 572 Labels: map[string]string{}, 573 574 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 575 } 576 expected := []string{ 577 "(?m)^COPY upload/scripts /destination/scripts", 578 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 579 "(?m)^RUN /usr/libexec/s2i/assemble", 580 "(?m)^CMD /destination/scripts/run", 581 } 582 expectedFiles := []string{ 583 filepath.Join(tempdir, "upload/src/server.js"), 584 filepath.Join(tempdir, "upload/scripts/run"), 585 } 586 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 587 } 588 589 func TestDockerfileBuildImageScriptsURLImage(t *testing.T) { 590 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 591 if err != nil { 592 t.Errorf("Unable to create temporary directory: %v", err) 593 } 594 defer os.RemoveAll(tempdir) 595 596 sourcecode := filepath.Join(tempdir, "sourcecode") 597 sourcescripts := filepath.Join(sourcecode, ".s2i", "bin") 598 err = os.MkdirAll(sourcescripts, 0777) 599 if err != nil { 600 t.Errorf("Unable to create injection dir: %v", err) 601 } 602 603 assemble := filepath.Join(sourcescripts, "assemble") 604 _, err = os.OpenFile(assemble, os.O_RDONLY|os.O_CREATE, 0666) 605 if err != nil { 606 t.Errorf("Unable to create assemble file: %v", err) 607 } 608 609 config := &api.Config{ 610 BuilderImage: "docker.io/centos/nodejs-8-centos7", 611 AssembleUser: "", 612 ImageWorkDir: "", 613 Source: git.MustParse("file:///" + filepath.ToSlash(sourcecode)), 614 ForceCopy: true, 615 ImageScriptsURL: "image:///usr/custom/s2i", 616 Injections: api.VolumeList{}, 617 Destination: "/destination", 618 619 Environment: api.EnvironmentList{}, 620 Labels: map[string]string{}, 621 622 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 623 } 624 expected := []string{ 625 "(?m)^COPY upload/scripts /destination/scripts", 626 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 627 "(?m)^RUN /destination/scripts/assemble", 628 "(?m)^CMD /usr/custom/s2i/run", 629 } 630 expectedFiles := []string{ 631 filepath.Join(tempdir, "upload/scripts/assemble"), 632 } 633 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 634 } 635 636 func TestDockerfileBuildScriptsAndImageURL(t *testing.T) { 637 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 638 if err != nil { 639 t.Errorf("Unable to create temporary directory: %v", err) 640 } 641 defer os.RemoveAll(tempdir) 642 643 assemble := filepath.Join(tempdir, "assemble") 644 _, err = os.OpenFile(assemble, os.O_RDONLY|os.O_CREATE, 0666) 645 if err != nil { 646 t.Errorf("Unable to create assemble file: %v", err) 647 } 648 649 config := &api.Config{ 650 BuilderImage: "docker.io/centos/nodejs-8-centos7", 651 AssembleUser: "", 652 ImageWorkDir: "", 653 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 654 ScriptsURL: "file://" + filepath.ToSlash(tempdir), 655 ImageScriptsURL: "image:///usr/some/dir", 656 Injections: api.VolumeList{}, 657 Destination: "/destination", 658 659 Environment: api.EnvironmentList{}, 660 Labels: map[string]string{}, 661 662 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 663 } 664 expected := []string{ 665 "(?m)^COPY upload/scripts /destination/scripts", 666 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 667 "(?m)^RUN /destination/scripts/assemble", 668 "(?m)^CMD /usr/some/dir/run", 669 } 670 expectedFiles := []string{ 671 filepath.Join(tempdir, "upload/src/server.js"), 672 filepath.Join(tempdir, "upload/scripts/assemble"), 673 } 674 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 675 } 676 677 // TestDockerfileBuildScriptsAndImageURLConflicts tests if both 678 // the ScriptsURL and ImageScriptsURL point to a non-image directory. 679 // In this event, the ScriptsURL value should take precedence. 680 func TestDockerfileBuildScriptsAndImageURLConflicts(t *testing.T) { 681 scriptsTempDir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 682 if err != nil { 683 t.Errorf("Unable to create temporary directory: %v", err) 684 } 685 defer os.RemoveAll(scriptsTempDir) 686 687 imageTempDir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 688 if err != nil { 689 t.Errorf("Unable to create temporary directory: %v", err) 690 } 691 defer os.RemoveAll(imageTempDir) 692 693 outputDir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 694 if err != nil { 695 t.Errorf("Unable to create temporary directory: %v", err) 696 } 697 defer os.RemoveAll(outputDir) 698 699 scriptsAssemble := filepath.Join(scriptsTempDir, "assemble") 700 assembleData := []byte("#!/bin/bash\necho \"Hello World!\"") 701 err = ioutil.WriteFile(scriptsAssemble, assembleData, 0666) 702 if err != nil { 703 t.Errorf("Unable to create image assemble file: %v", err) 704 } 705 706 imageAssemble := filepath.Join(imageTempDir, "assemble") 707 _, err = os.OpenFile(imageAssemble, os.O_RDONLY|os.O_CREATE, 0666) 708 if err != nil { 709 t.Errorf("Unable to create assemble file: %v", err) 710 } 711 712 config := &api.Config{ 713 BuilderImage: "docker.io/centos/nodejs-8-centos7", 714 AssembleUser: "", 715 ImageWorkDir: "", 716 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 717 ScriptsURL: "file://" + filepath.ToSlash(scriptsTempDir), 718 ImageScriptsURL: "file://" + filepath.ToSlash(imageTempDir), 719 Injections: api.VolumeList{}, 720 Destination: "/destination", 721 722 Environment: api.EnvironmentList{}, 723 Labels: map[string]string{}, 724 725 AsDockerfile: filepath.Join(outputDir, "Dockerfile"), 726 } 727 expected := []string{ 728 "(?m)^COPY upload/scripts /destination/scripts", 729 "(?m)^RUN chown -R 1001:0.* /destination/scripts", 730 "(?m)^RUN /destination/scripts/assemble", 731 "(?m)^CMD /usr/libexec/s2i/run", 732 } 733 expectedFiles := []string{ 734 filepath.Join(outputDir, "upload/src/server.js"), 735 filepath.Join(outputDir, "upload/scripts/assemble"), 736 } 737 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 738 dockerfileAssemble, err := ioutil.ReadFile(filepath.Join(outputDir, "upload/scripts/assemble")) 739 if err != nil { 740 t.Errorf("Failed to read uploaded assemble script: %v", err) 741 } 742 if string(dockerfileAssemble) != string(assembleData) { 743 t.Errorf("Expected uploaded assemble script:\n\n%s\n\nto be:\n\n%s", dockerfileAssemble, assembleData) 744 } 745 } 746 747 func TestDockerfileIncrementalBuild(t *testing.T) { 748 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 749 if err != nil { 750 t.Errorf("Unable to create temporary directory: %v", err) 751 } 752 defer os.RemoveAll(tempdir) 753 754 config := &api.Config{ 755 BuilderImage: "docker.io/centos/nodejs-8-centos7", 756 AssembleUser: "", 757 ImageWorkDir: "", 758 Incremental: true, 759 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 760 ScriptsURL: "", 761 Tag: "test:tag", 762 Injections: api.VolumeList{}, 763 Destination: "", 764 765 Environment: api.EnvironmentList{}, 766 Labels: map[string]string{}, 767 768 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 769 } 770 771 expected := []string{ 772 "(?m)^FROM test:tag as cached\n#.+\nUSER 1001", 773 "(?m)^RUN if \\[ -s /usr/libexec/s2i/save-artifacts \\]; then /usr/libexec/s2i/save-artifacts > /tmp/artifacts.tar; else touch /tmp/artifacts.tar; fi", 774 "(?m)^FROM docker.io/centos/nodejs-8-centos7", 775 "(?m)^COPY --from=cached /tmp/artifacts.tar /tmp/artifacts.tar", 776 "(?m)^RUN chown -R 1001:0.* /tmp/artifacts.tar", 777 "if \\[ -s /tmp/artifacts.tar \\]; then mkdir -p /tmp/artifacts; tar -xf /tmp/artifacts.tar -C /tmp/artifacts; fi", 778 "rm /tmp/artifacts.tar", 779 "(?m)^COPY upload/src /tmp/src", 780 "(?m)^RUN chown -R 1001:0.* /tmp/src", 781 "(?m)^RUN /usr/libexec/s2i/assemble", 782 "(?m)^CMD /usr/libexec/s2i/run", 783 } 784 785 runDockerfileTest(t, config, expected, nil, nil, false) 786 } 787 788 func TestDockerfileIncrementalSourceSave(t *testing.T) { 789 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 790 if err != nil { 791 t.Errorf("Unable to create temporary directory: %v", err) 792 } 793 defer os.RemoveAll(tempdir) 794 795 sourcecode := filepath.Join(tempdir, "sourcecode") 796 sourcescripts := filepath.Join(sourcecode, ".s2i", "bin") 797 err = os.MkdirAll(sourcescripts, 0777) 798 if err != nil { 799 t.Errorf("Unable to create injection dir: %v", err) 800 } 801 802 saveArtifacts := filepath.Join(sourcescripts, "save-artifacts") 803 _, err = os.OpenFile(saveArtifacts, os.O_RDONLY|os.O_CREATE, 0666) 804 if err != nil { 805 t.Errorf("Unable to create save-artifacts file: %v", err) 806 } 807 808 config := &api.Config{ 809 BuilderImage: "docker.io/centos/nodejs-8-centos7", 810 AssembleUser: "", 811 ImageWorkDir: "", 812 Incremental: true, 813 Source: git.MustParse("file:///" + filepath.ToSlash(sourcecode)), 814 ScriptsURL: "", 815 Tag: "test:tag", 816 Injections: api.VolumeList{}, 817 Destination: "/destination", 818 819 Environment: api.EnvironmentList{}, 820 Labels: map[string]string{}, 821 822 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 823 } 824 825 expected := []string{ 826 "(?m)^FROM test:tag as cached\n#.+\nUSER root\n", 827 "(?m)^COPY upload/scripts/save-artifacts /destination/scripts/save-artifacts", 828 "(?m)^RUN chown .*1001:0 /destination/scripts/save-artifacts", 829 "(?m)^USER 1001\nRUN if \\[ -s /destination/scripts/save-artifacts \\]; then /destination/scripts/save-artifacts > /tmp/artifacts.tar;", 830 "(?m)^FROM docker.io/centos/nodejs-8-centos7", 831 "mkdir -p /destination/artifacts", 832 "tar -xf /tmp/artifacts.tar -C /destination/artifacts", 833 "(?m)^RUN /usr/libexec/s2i/assemble", 834 "(?m)^CMD /usr/libexec/s2i/run", 835 } 836 expectedFiles := []string{ 837 filepath.Join(tempdir, "upload/scripts/save-artifacts"), 838 } 839 840 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 841 } 842 843 func TestDockerfileIncrementalSaveURL(t *testing.T) { 844 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 845 if err != nil { 846 t.Errorf("Unable to create temporary directory: %v", err) 847 } 848 defer os.RemoveAll(tempdir) 849 850 saveArtifacts := filepath.Join(tempdir, "save-artifacts") 851 _, err = os.OpenFile(saveArtifacts, os.O_RDONLY|os.O_CREATE, 0666) 852 if err != nil { 853 t.Errorf("Unable to create save-artifacts file: %v", err) 854 } 855 856 config := &api.Config{ 857 BuilderImage: "docker.io/centos/nodejs-8-centos7", 858 AssembleUser: "", 859 ImageWorkDir: "", 860 Incremental: true, 861 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 862 ScriptsURL: "file://" + filepath.ToSlash(tempdir), 863 Tag: "test:tag", 864 Injections: api.VolumeList{}, 865 Destination: "/destination", 866 867 Environment: api.EnvironmentList{}, 868 Labels: map[string]string{}, 869 870 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 871 } 872 873 expected := []string{ 874 "(?m)^FROM test:tag as cached\n#.+\nUSER root\n", 875 "(?m)^COPY upload/scripts/save-artifacts /destination/scripts/save-artifacts", 876 "(?m)^RUN chown 1001:0 /destination/scripts/save-artifacts", 877 "(?m)^USER 1001\nRUN if \\[ -s /destination/scripts/save-artifacts \\]; then /destination/scripts/save-artifacts > /tmp/artifacts.tar;", 878 "(?m)^FROM docker.io/centos/nodejs-8-centos7", 879 "mkdir -p /destination/artifacts", 880 "tar -xf /tmp/artifacts.tar -C /destination/artifacts", 881 "(?m)^RUN /usr/libexec/s2i/assemble", 882 "(?m)^CMD /usr/libexec/s2i/run", 883 } 884 expectedFiles := []string{ 885 filepath.Join(tempdir, "upload/scripts/save-artifacts"), 886 } 887 888 runDockerfileTest(t, config, expected, nil, expectedFiles, false) 889 } 890 891 func TestDockerfileIncrementalTag(t *testing.T) { 892 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 893 if err != nil { 894 t.Errorf("Unable to create temporary directory: %v", err) 895 } 896 defer os.RemoveAll(tempdir) 897 898 config := &api.Config{ 899 BuilderImage: "docker.io/centos/nodejs-8-centos7", 900 AssembleUser: "", 901 ImageWorkDir: "", 902 Incremental: true, 903 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 904 Tag: "test:tag", 905 IncrementalFromTag: "incremental:tag", 906 907 Environment: api.EnvironmentList{}, 908 Labels: map[string]string{}, 909 910 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 911 } 912 913 expected := []string{ 914 "(?m)^FROM incremental:tag as cached", 915 "/usr/libexec/s2i/save-artifacts > /tmp/artifacts.tar", 916 "(?m)^FROM docker.io/centos/nodejs-8-centos7", 917 "mkdir -p /tmp/artifacts", 918 "tar -xf /tmp/artifacts.tar -C /tmp/artifacts", 919 "rm /tmp/artifacts.tar", 920 "(?m)^RUN /usr/libexec/s2i/assemble", 921 "(?m)^CMD /usr/libexec/s2i/run", 922 } 923 924 runDockerfileTest(t, config, expected, nil, nil, false) 925 } 926 927 func TestDockerfileIncrementalAssembleUser(t *testing.T) { 928 tempdir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 929 if err != nil { 930 t.Errorf("Unable to create temporary directory: %v", err) 931 } 932 defer os.RemoveAll(tempdir) 933 934 config := &api.Config{ 935 BuilderImage: "docker.io/centos/nodejs-8-centos7", 936 AssembleUser: "2250", 937 ImageWorkDir: "", 938 Incremental: true, 939 Source: git.MustParse("https://github.com/sclorg/nodejs-ex"), 940 Tag: "test:tag", 941 Environment: api.EnvironmentList{}, 942 Labels: map[string]string{}, 943 944 AsDockerfile: filepath.Join(tempdir, "Dockerfile"), 945 } 946 947 expected := []string{ 948 "(?m)^FROM test:tag as cached\n#.+\nUSER 2250", 949 "/usr/libexec/s2i/save-artifacts > /tmp/artifacts.tar", 950 "(?m)^FROM docker.io/centos/nodejs-8-centos7", 951 "(?m)^COPY --from=cached /tmp/artifacts.tar /tmp/artifacts.tar", 952 "(?m)^RUN chown -R 2250:0 .*/tmp/artifacts.tar", 953 "mkdir -p /tmp/artifacts", 954 "tar -xf /tmp/artifacts.tar -C /tmp/artifacts", 955 "rm /tmp/artifacts.tar", 956 "(?m)^RUN /usr/libexec/s2i/assemble", 957 "(?m)^CMD /usr/libexec/s2i/run", 958 } 959 960 runDockerfileTest(t, config, expected, nil, nil, false) 961 } 962 963 func TestDockerfileLocalSource(t *testing.T) { 964 localTempDir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 965 if err != nil { 966 t.Errorf("Unable to create temporary directory: %v", err) 967 } 968 defer os.RemoveAll(localTempDir) 969 970 outputDir, err := ioutil.TempDir("", "s2i-dockerfiletest-dir") 971 if err != nil { 972 t.Errorf("Unable to create temporary directory: %v", err) 973 } 974 defer os.RemoveAll(outputDir) 975 976 config := &api.Config{ 977 BuilderImage: "sti_test/sti-fake", 978 Source: git.MustParse("file:///" + filepath.ToSlash(localTempDir)), 979 AsDockerfile: filepath.Join(outputDir, "Dockerfile"), 980 } 981 982 dirTree := []string{ 983 "foo/bar", 984 "foo/baz/foobar", 985 } 986 for _, dirName := range dirTree { 987 err = os.MkdirAll(filepath.Join(localTempDir, dirName), 0777) 988 if err != nil { 989 t.Errorf("Unable to create dir: %v", err) 990 } 991 } 992 993 fileTree := []string{ 994 "foo/a_file", 995 "foo/bar/a_file", 996 "foo/bar/another_file", 997 "foo/baz/foobar/a_file", 998 } 999 for _, fileName := range fileTree { 1000 dummyContent := []byte("Hello World!") 1001 err = ioutil.WriteFile(filepath.Join(localTempDir, fileName), dummyContent, 0666) 1002 if err != nil { 1003 t.Errorf("Unable to create file: %v", err) 1004 } 1005 } 1006 1007 expectedFiles := []string{ 1008 filepath.Join(outputDir, "upload/src/foo/a_file"), 1009 filepath.Join(outputDir, "upload/src/foo/bar"), 1010 filepath.Join(outputDir, "upload/src/foo/bar/a_file"), 1011 filepath.Join(outputDir, "upload/src/foo/bar/another_file"), 1012 filepath.Join(outputDir, "upload/src/foo/baz/foobar"), 1013 filepath.Join(outputDir, "upload/src/foo/baz/foobar/a_file"), 1014 } 1015 1016 runDockerfileTest(t, config, nil, nil, expectedFiles, false) 1017 1018 s2iignore := filepath.Join(localTempDir, ".s2iignore") 1019 s2iignoreDate := []byte("dummy\n#skip_file\nfoo/bar/another_file\nfoo/baz/foobar") 1020 err = ioutil.WriteFile(s2iignore, s2iignoreDate, 0666) 1021 if err != nil { 1022 t.Errorf("Unable to create .s2iignore file: %v", err) 1023 } 1024 1025 expectedFiles = []string{ 1026 filepath.Join(outputDir, "upload/src/foo/a_file"), 1027 filepath.Join(outputDir, "upload/src/foo/bar"), 1028 filepath.Join(outputDir, "upload/src/foo/bar/a_file"), 1029 } 1030 1031 runDockerfileTest(t, config, nil, nil, expectedFiles, false) 1032 } 1033 1034 func runDockerfileTest(t *testing.T, config *api.Config, expected []string, notExpected []string, expectedFiles []string, expectFailure bool) { 1035 1036 b, _, err := strategies.GetStrategy(nil, config) 1037 if err != nil { 1038 t.Fatalf("Cannot create a new builder.") 1039 } 1040 resp, err := b.Build(config) 1041 if expectFailure { 1042 if err == nil || resp.Success { 1043 t.Errorf("The build succeded when it should have failed. Success: %t, error: %v", resp.Success, err) 1044 } 1045 return 1046 } 1047 if err != nil { 1048 t.Fatalf("An error occurred during the build: %v", err) 1049 } 1050 if !resp.Success { 1051 t.Fatalf("The build failed when it should have succeeded.") 1052 } 1053 1054 filebytes, err := ioutil.ReadFile(config.AsDockerfile) 1055 if err != nil { 1056 t.Fatalf("An error occurred reading the dockerfile: %v", err) 1057 } 1058 dockerfile := string(filebytes) 1059 1060 buf := bytes.NewBuffer(filebytes) 1061 _, err = parser.Parse(buf) 1062 if err != nil { 1063 t.Fatalf("An error occurred parsing the dockerfile: %v\n%s", err, dockerfile) 1064 } 1065 1066 for _, s := range expected { 1067 reg, err := regexp.Compile(s) 1068 if err != nil { 1069 t.Fatalf("failed to compile regex %q: %v", s, err) 1070 } 1071 if !reg.MatchString(dockerfile) { 1072 t.Fatalf("Expected dockerfile to contain %s, it did not: \n%s", s, dockerfile) 1073 } 1074 } 1075 for _, s := range notExpected { 1076 reg, err := regexp.Compile(s) 1077 if err != nil { 1078 t.Fatalf("failed to compile regex %q: %v", s, err) 1079 } 1080 if reg.MatchString(dockerfile) { 1081 t.Fatalf("Expected dockerfile not to contain %s, it did: \n%s", s, dockerfile) 1082 } 1083 } 1084 for _, f := range expectedFiles { 1085 if _, err := os.Stat(f); os.IsNotExist(err) { 1086 t.Fatalf("Did not find expected file %s, ", f) 1087 } 1088 } 1089 }