- // Package docker implements a compiler for turning Blubber configuration into
- // a valid single- or multi-stage Dockerfile.
- //
- package docker
-
- import (
- "bytes"
-
- "gerrit.wikimedia.org/r/blubber/build"
- "gerrit.wikimedia.org/r/blubber/config"
- "gerrit.wikimedia.org/r/blubber/meta"
- )
-
- // Compile takes a parsed config.Config and a configured variant name and
- // returns the bytes of a resulting Dockerfile. In the case where artifacts
- // are defined or the shorthand "copies" configured is set, a multi-stage
- // Dockerfile will be returned.
- //
- func Compile(cfg *config.Config, variant string) (*bytes.Buffer, error) {
- buffer := new(bytes.Buffer)
-
- vcfg, err := config.ExpandVariant(cfg, variant)
-
- if err != nil {
- return nil, err
- }
-
- // omit the main stage name unless multi-stage is required below
- mainStage := ""
-
- // write multi-stage sections for each variant dependency
- for _, stage := range vcfg.Copies.Variants() {
- dependency, err := config.ExpandVariant(cfg, stage)
-
- if err != nil {
- return nil, err
- }
-
- compileStage(buffer, stage, dependency)
- mainStage = variant
- }
-
- compileStage(buffer, mainStage, vcfg)
-
- // add meta-data labels to the final stage
- compileInstructions(buffer, build.Label{map[string]string{
- "blubber.variant": variant,
- "blubber.version": meta.FullVersion(),
- }})
-
- return buffer, nil
- }
-
- func compileStage(buffer *bytes.Buffer, stage string, vcfg *config.VariantConfig) {
- baseAndStage := vcfg.Base
-
- if stage != "" {
- baseAndStage += " AS " + stage
- }
-
- writeln(buffer, "FROM ", baseAndStage)
-
- for _, phase := range build.Phases() {
- compilePhase(buffer, vcfg, phase)
- }
- }
-
- func compileInstructions(buffer *bytes.Buffer, instructions ...build.Instruction) {
- for _, instruction := range instructions {
- dockerInstruction, _ := NewInstruction(instruction)
- write(buffer, dockerInstruction.Compile())
- }
- }
-
- func compilePhase(buffer *bytes.Buffer, vcfg *config.VariantConfig, phase build.Phase) {
- compileInstructions(buffer, vcfg.InstructionsForPhase(phase)...)
- }
-
- func write(buffer *bytes.Buffer, strings ...string) {
- for _, str := range strings {
- buffer.WriteString(str)
- }
- }
-
- func writeln(buffer *bytes.Buffer, strings ...string) {
- write(buffer, strings...)
- buffer.WriteString("\n")
- }
|