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.

115 lines
2.7 KiB

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
  1. package config
  2. import (
  3. "encoding/json"
  4. "gerrit.wikimedia.org/r/blubber/build"
  5. )
  6. // LocalArtifactKeyword defines a special keyword indicating
  7. // file/directory artifacts to be copied from the local build host context.
  8. //
  9. const LocalArtifactKeyword = "local"
  10. // CopiesConfig holds configuration for which files to copy into the variant
  11. // from local and other variant sources.
  12. //
  13. type CopiesConfig []ArtifactsConfig
  14. // Expand returns a version of this CopiesConfig with its shorthand
  15. // configurations expanded.
  16. //
  17. func (cc *CopiesConfig) Expand(appDirectory string) CopiesConfig {
  18. expanded := CopiesConfig{}
  19. // expand all artifact definitions
  20. for _, artifact := range *cc {
  21. expanded = append(expanded, artifact.Expand(appDirectory)...)
  22. }
  23. return expanded
  24. }
  25. // InstructionsForPhase delegates to its member ArtifactsConfig.
  26. //
  27. func (cc CopiesConfig) InstructionsForPhase(phase build.Phase) []build.Instruction {
  28. instructions := []build.Instruction{}
  29. for _, artifact := range cc {
  30. instructions = append(instructions, artifact.InstructionsForPhase(phase)...)
  31. }
  32. return instructions
  33. }
  34. // Merge takes another CopiesConfig and overwrites this struct's fields.
  35. //
  36. // Artifacts are merged additively and duplicates are removed. Uniqueness is
  37. // ensured by taking the latest definition over the previous.
  38. //
  39. func (cc *CopiesConfig) Merge(cc2 CopiesConfig) {
  40. // efficient search of the other CopiesConfig using a map
  41. newlyDefined := make(map[ArtifactsConfig]bool, len(*cc))
  42. for _, artifact := range cc2 {
  43. newlyDefined[artifact] = true
  44. }
  45. dupesRemoved := CopiesConfig{}
  46. // omit any previously defined artifacts that are among the new
  47. for _, artifact := range *cc {
  48. if !newlyDefined[artifact] {
  49. dupesRemoved = append(dupesRemoved, artifact)
  50. }
  51. }
  52. *cc = append(dupesRemoved, cc2...)
  53. }
  54. // UnmarshalJSON implements json.Unmarshaler to handle both shorthand and
  55. // longhand copies configuration.
  56. //
  57. func (cc *CopiesConfig) UnmarshalJSON(unmarshal []byte) error {
  58. shorthand := []string{}
  59. err := json.Unmarshal(unmarshal, &shorthand)
  60. if err == nil {
  61. *cc = make(CopiesConfig, len(shorthand))
  62. for i, variant := range shorthand {
  63. (*cc)[i] = ArtifactsConfig{From: variant}
  64. }
  65. return nil
  66. }
  67. longhand := []ArtifactsConfig{}
  68. err = json.Unmarshal(unmarshal, &longhand)
  69. if err == nil {
  70. *cc = CopiesConfig(longhand)
  71. return nil
  72. }
  73. return err
  74. }
  75. // Variants returns a unique slice of variant names that are referenced by
  76. // artifact definitions.
  77. //
  78. func (cc *CopiesConfig) Variants() []string {
  79. existing := map[string]bool{}
  80. variants := []string{}
  81. for _, artifact := range *cc {
  82. if v := artifact.From; v != "" && v != LocalArtifactKeyword && !existing[v] {
  83. existing[v] = true
  84. variants = append(variants, v)
  85. }
  86. }
  87. return variants
  88. }