You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.2 KiB

7 years ago
7 years ago
7 years ago
Unify `copies` and `artifacts` configuration Refactored `copies` configuration to allow for greater control over when and which both local build context files and variant artifacts are copied into the target image. The new configuration introduces a "local" keyword to signify when a `copies` entry should apply to the files from the local build context as opposed to files from another variant's image during a multi-stage build. variants: build: copies: - from: local source: ./src destination: . Note that with this change, the user must now explicitly define whether _any_ files should be copied in from the local build context. None will be copied in by default. To help keep configurations succinct, especially considering this new requirement, and to approximate the old `copies: variant`, a shorthand format and sane defaults for `source` and `destination` (depending whether `from` is "local" or a variant name) were implemented. variants: build: copies: [local] development: copies: - from: build - from: local source: ./config.dev.yaml destination: ./config.yaml The shorthand: copies: [ref, ...] # is equivalent to copies: [{ from: ref }, ...] And the following defaults are used when no `source` and `destination` are specified. copies: - from: local # defaults to - from: local source: . destination: . copies: - from: variant # defaults to two entries - from: variant source: /srv/app # the lives.in dir destination: /srv/app - from: variant source: /opt/local # the shared lib dir destination: /opt/local Bug: T211625 Change-Id: I4c4217905afc0762b6bd66ed594d43cc0486e3e2
5 years ago
7 years ago
  1. // Package docker implements a compiler for turning Blubber configuration into
  2. // a valid single- or multi-stage Dockerfile.
  3. //
  4. package docker
  5. import (
  6. "bytes"
  7. "gerrit.wikimedia.org/r/blubber/build"
  8. "gerrit.wikimedia.org/r/blubber/config"
  9. "gerrit.wikimedia.org/r/blubber/meta"
  10. )
  11. // Compile takes a parsed config.Config and a configured variant name and
  12. // returns the bytes of a resulting Dockerfile. In the case where artifacts
  13. // are defined or the shorthand "copies" configured is set, a multi-stage
  14. // Dockerfile will be returned.
  15. //
  16. func Compile(cfg *config.Config, variant string) (*bytes.Buffer, error) {
  17. buffer := new(bytes.Buffer)
  18. vcfg, err := config.ExpandVariant(cfg, variant)
  19. if err != nil {
  20. return nil, err
  21. }
  22. // omit the main stage name unless multi-stage is required below
  23. mainStage := ""
  24. // write multi-stage sections for each variant dependency
  25. for _, stage := range vcfg.Copies.Variants() {
  26. dependency, err := config.ExpandVariant(cfg, stage)
  27. if err != nil {
  28. return nil, err
  29. }
  30. compileStage(buffer, stage, dependency)
  31. mainStage = variant
  32. }
  33. compileStage(buffer, mainStage, vcfg)
  34. // add meta-data labels to the final stage
  35. compileInstructions(buffer, build.Label{map[string]string{
  36. "blubber.variant": variant,
  37. "blubber.version": meta.FullVersion(),
  38. }})
  39. return buffer, nil
  40. }
  41. func compileStage(buffer *bytes.Buffer, stage string, vcfg *config.VariantConfig) {
  42. baseAndStage := vcfg.Base
  43. if stage != "" {
  44. baseAndStage += " AS " + stage
  45. }
  46. writeln(buffer, "FROM ", baseAndStage)
  47. for _, phase := range build.Phases() {
  48. compilePhase(buffer, vcfg, phase)
  49. }
  50. }
  51. func compileInstructions(buffer *bytes.Buffer, instructions ...build.Instruction) {
  52. for _, instruction := range instructions {
  53. dockerInstruction, _ := NewInstruction(instruction)
  54. write(buffer, dockerInstruction.Compile())
  55. }
  56. }
  57. func compilePhase(buffer *bytes.Buffer, vcfg *config.VariantConfig, phase build.Phase) {
  58. compileInstructions(buffer, vcfg.InstructionsForPhase(phase)...)
  59. }
  60. func write(buffer *bytes.Buffer, strings ...string) {
  61. for _, str := range strings {
  62. buffer.WriteString(str)
  63. }
  64. }
  65. func writeln(buffer *bytes.Buffer, strings ...string) {
  66. write(buffer, strings...)
  67. buffer.WriteString("\n")
  68. }