diff options
author | Dan Duvall <dduvall@wikimedia.org> | 2017-10-24 18:04:47 -0700 |
---|---|---|
committer | Dan Duvall <dduvall@wikimedia.org> | 2017-11-06 13:25:20 -0800 |
commit | 515d9f26eb616a9c3a0b70ba6eca88570a15b0ef (patch) | |
tree | 0f8d3b0a6381f4ea2c43ce063f6af9990a2abb2f /config | |
parent | 5d4cc80edf4fdba60069a7ef1e450117195fb987 (diff) | |
download | blubber-515d9f26eb616a9c3a0b70ba6eca88570a15b0ef.tar.gz |
Documented all exported types, functions, and interfaces
Summary:
Wrote inline documentation for all the things.
Fixes T168000
Test Plan: Execute `godoc -http=:6060` and proofread all the things.
Reviewers: thcipriani, hashar, #release-engineering-team, demon
Reviewed By: thcipriani, #release-engineering-team, demon
Tags: #release-engineering-team
Maniphest Tasks: T168000
Differential Revision: https://phabricator.wikimedia.org/D841
Diffstat (limited to 'config')
-rw-r--r-- | config/apt.go | 13 | ||||
-rw-r--r-- | config/artifacts.go | 24 | ||||
-rw-r--r-- | config/common.go | 24 | ||||
-rw-r--r-- | config/config.go | 6 | ||||
-rw-r--r-- | config/flag.go | 9 | ||||
-rw-r--r-- | config/node.go | 31 | ||||
-rw-r--r-- | config/reader.go | 6 | ||||
-rw-r--r-- | config/runs.go | 37 | ||||
-rw-r--r-- | config/variant.go | 24 |
9 files changed, 155 insertions, 19 deletions
diff --git a/config/apt.go b/config/apt.go index e1f8f53..3a7a688 100644 --- a/config/apt.go +++ b/config/apt.go @@ -4,14 +4,27 @@ import ( "phabricator.wikimedia.org/source/blubber/build" ) +// AptConfig represents configuration pertaining to package installation from +// existing APT sources. +// type AptConfig struct { Packages []string `yaml:"packages"` } +// Merge takes another AptConfig and combines the packages declared within +// with the packages of this AptConfig. +// func (apt *AptConfig) Merge(apt2 AptConfig) { apt.Packages = append(apt.Packages, apt2.Packages...) } +// InstructionsForPhase injects build instructions that will install the +// declared packages during the privileged phase. +// +// PhasePrivileged +// +// Updates the APT cache, installs configured packages, and cleans up. +// func (apt AptConfig) InstructionsForPhase(phase build.Phase) []build.Instruction { if len(apt.Packages) > 0 { switch phase { diff --git a/config/artifacts.go b/config/artifacts.go index 654f10f..bd1bdeb 100644 --- a/config/artifacts.go +++ b/config/artifacts.go @@ -4,12 +4,30 @@ import ( "phabricator.wikimedia.org/source/blubber/build" ) +// ArtifactsConfig declares files and directories to be copied from one +// variant's container to another during the build. +// +// The most common use of such "multi-stage" builds is to compile and test +// software using one variant image that contains a comprehensive set of +// development dependencies, and copy the software binaries or production only +// source files over into a smaller image that contains only production +// dependencies. For a shorthand configuration of this precise pattern, use +// VariantConfig.Copies. +// type ArtifactsConfig struct { - From string `yaml:"from"` - Source string `yaml:"source"` - Destination string `yaml:"destination"` + From string `yaml:"from"` // source variant from which to copy + Source string `yaml:"source"` // source path within variant from which to copy + Destination string `yaml:"destination"` // destination path within current variant } +// InstructionsForPhase injects instructions into the given build phase that +// copy configured artifacts. +// +// PhasePostInstall +// +// Injects build.CopyFrom instructions for the configured source and +// destination paths. +// func (ac ArtifactsConfig) InstructionsForPhase(phase build.Phase) []build.Instruction { switch phase { case build.PhasePostInstall: diff --git a/config/common.go b/config/common.go index dae0013..11357d8 100644 --- a/config/common.go +++ b/config/common.go @@ -4,15 +4,20 @@ import ( "phabricator.wikimedia.org/source/blubber/build" ) +// CommonConfig holds the configuration fields common to both the root config +// and each configured variant. +// type CommonConfig struct { - Base string `yaml:"base"` - Apt AptConfig `yaml:"apt"` - Node NodeConfig `yaml:"node"` - Runs RunsConfig `yaml:"runs"` - SharedVolume Flag `yaml:"sharedvolume"` - EntryPoint []string `yaml:"entrypoint"` + Base string `yaml:"base"` // name/path to base image + Apt AptConfig `yaml:"apt"` // APT related configuration + Node NodeConfig `yaml:"node"` // Node related configuration + Runs RunsConfig `yaml:"runs"` // runtime environment configuration + SharedVolume Flag `yaml:"sharedvolume"` // define a volume instead of copying in source files + EntryPoint []string `yaml:"entrypoint"` // entry-point executable } +// Merge takes another CommonConfig and merges its fields this one's. +// func (cc1 *CommonConfig) Merge(cc2 CommonConfig) { if cc2.Base != "" { cc1.Base = cc2.Base @@ -28,10 +33,17 @@ func (cc1 *CommonConfig) Merge(cc2 CommonConfig) { } } +// PhaseCompileableConfig returns all fields that implement +// build.PhaseCompileable in the order that their instructions should be +// injected. +// func (cc *CommonConfig) PhaseCompileableConfig() []build.PhaseCompileable { return []build.PhaseCompileable{cc.Apt, cc.Node, cc.Runs} } +// InstructionsForPhase injects instructions into the given build phase for +// each member field that supports it. +// func (cc *CommonConfig) InstructionsForPhase(phase build.Phase) []build.Instruction { instructions := []build.Instruction{} diff --git a/config/config.go b/config/config.go index 6f4283f..3360012 100644 --- a/config/config.go +++ b/config/config.go @@ -1,5 +1,11 @@ +// Package config provides the internal representation of Blubber +// configuration parsed from YAML. Each configuration type may implement +// its own hooks for injecting build instructions into the compiler. +// package config +// Config holds the root fields of a Blubber configuration. +// type Config struct { CommonConfig `yaml:",inline"` Variants map[string]VariantConfig `yaml:"variants"` diff --git a/config/flag.go b/config/flag.go index b841819..6fb9e72 100644 --- a/config/flag.go +++ b/config/flag.go @@ -1,10 +1,16 @@ package config +// Flag represents a nullable boolean value that is considered null until +// either parsed from YAML or merged in from another Flag value. +// type Flag struct { True bool set bool } +// UnmarshalYAML implements yaml.Unmarshaler to parse the underlying boolean +// value and detect that the Flag should no longer be considered null. +// func (flag *Flag) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := unmarshal(&flag.True); err != nil { return err @@ -15,6 +21,9 @@ func (flag *Flag) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } +// Merge takes another flag and, if set, merged its boolean value into this +// one. +// func (flag *Flag) Merge(flag2 Flag) { if flag2.set { flag.True = flag2.True diff --git a/config/node.go b/config/node.go index 90859e8..561c915 100644 --- a/config/node.go +++ b/config/node.go @@ -5,11 +5,17 @@ import ( "phabricator.wikimedia.org/source/blubber/build" ) +// NodeConfig holds configuration fields related to the Node environment and +// whether/how to install NPM packages. +// type NodeConfig struct { - Dependencies Flag `yaml:"dependencies"` - Env string `yaml:"env"` + Dependencies Flag `yaml:"dependencies"` // install dependencies declared in package.json + Env string `yaml:"env"` // environment name ("production" install) } +// Merge takes another NodeConfig and merges its fields into this one's, +// overwriting both the environment and dependencies flag. +// func (nc *NodeConfig) Merge(nc2 NodeConfig) { nc.Dependencies.Merge(nc2.Dependencies) @@ -18,6 +24,27 @@ func (nc *NodeConfig) Merge(nc2 NodeConfig) { } } +// InstructionsForPhase injects instructions into the build related to Node +// dependency installation and setting of the NODE_ENV, NODE_PATH, and PATH +// environment variables. +// +// PhasePreInstall +// +// Installs Node package dependencies declared in package.json into the shared +// library directory (/opt/lib). Only production related packages are install +// if NodeConfig.Env is set to "production" in which case `npm dedupe` is also +// run. Installing dependencies during the build.PhasePreInstall phase allows +// a compiler implementation (e.g. Docker) to produce cache-efficient output +// so only changes to package.json will invalidate these steps of the image +// build. +// +// PhasePostInstall +// +// Injects build.Env instructions for NODE_ENV, NODE_PATH, and PATH, setting +// the environment according to the configuration, ensuring that packages +// installed during build.PhasePreInstall are found by Node, and that any +// installed binaries are found by shells. +// func (nc NodeConfig) InstructionsForPhase(phase build.Phase) []build.Instruction { switch phase { case build.PhasePreInstall: diff --git a/config/reader.go b/config/reader.go index 0f4cc12..7aa060d 100644 --- a/config/reader.go +++ b/config/reader.go @@ -35,6 +35,7 @@ func expandIncludes(config *Config, name string, included map[string]bool) ([]st // ExpandVariant merges a named variant with a config. It also attempts to // recursively expand any included variants in the expanded variant. +// func ExpandVariant(config *Config, name string) (*VariantConfig, error) { expanded := new(VariantConfig) expanded.CommonConfig.Merge(config.CommonConfig) @@ -53,6 +54,8 @@ func ExpandVariant(config *Config, name string) (*VariantConfig, error) { return expanded, nil } +// ReadConfig unmarshals the given YAML bytes into a Config struct. +// func ReadConfig(data []byte) (*Config, error) { var config Config @@ -61,6 +64,9 @@ func ReadConfig(data []byte) (*Config, error) { return &config, err } +// ReadConfigFile unmarshals the given YAML file contents into a Config +// struct. +// func ReadConfigFile(path string) (*Config, error) { data, err := ioutil.ReadFile(path) diff --git a/config/runs.go b/config/runs.go index 6a176c3..ef9f4ea 100644 --- a/config/runs.go +++ b/config/runs.go @@ -6,16 +6,26 @@ import ( "phabricator.wikimedia.org/source/blubber/build" ) +// LocalLibPrefix declares the shared directory into which application level +// dependencies will be installed. +// const LocalLibPrefix = "/opt/lib" +// RunsConfig holds configuration fields related to the application's +// runtime environment. +// type RunsConfig struct { - In string `yaml:"in"` - As string `yaml:"as"` - Uid int `yaml:"uid"` - Gid int `yaml:"gid"` - Environment map[string]string `yaml:"environment"` + In string `yaml:"in"` // working directory + As string `yaml:"as"` // unprivileged user + Uid int `yaml:"uid"` // unprivileged UID + Gid int `yaml:"gid"` // unprivileged GID + Environment map[string]string `yaml:"environment"` // environment variables } +// Merge takes another RunsConfig and overwrites this struct's fields. All +// fields except Environment are overwritten if set. The latter is an additive +// merge. +// func (run *RunsConfig) Merge(run2 RunsConfig) { if run2.In != "" { run.In = run2.In @@ -39,6 +49,9 @@ func (run *RunsConfig) Merge(run2 RunsConfig) { } } +// Home returns the home directory for the configured user, or /root if no +// user is set. +// func (run RunsConfig) Home() string { if run.As == "" { return "/root" @@ -47,6 +60,20 @@ func (run RunsConfig) Home() string { } } +// InstructionsForPhase injects build instructions related to the runtime +// configuration. +// +// PhasePrivileged +// +// Creates LocalLibPrefix directory and unprivileged user home directory, +// creates the unprivileged user and its group, and sets up directory +// permissions. +// +// PhasePrivilegeDropped +// +// Injects build.Env instructions for the user home directory and all +// names/values defined by RunsConfig.Environment. +// func (run RunsConfig) InstructionsForPhase(phase build.Phase) []build.Instruction { ins := []build.Instruction{} diff --git a/config/variant.go b/config/variant.go index 8e53b70..60fa325 100644 --- a/config/variant.go +++ b/config/variant.go @@ -4,19 +4,34 @@ import ( "phabricator.wikimedia.org/source/blubber/build" ) +// VariantConfig holds configuration fields for each defined build variant. +// type VariantConfig struct { - Includes []string `yaml:"includes"` - Copies string `yaml:"copies"` - Artifacts []ArtifactsConfig `yaml:"artifacts"` + Includes []string `yaml:"includes"` // references to one or more + Copies string `yaml:"copies"` // copy standard artifacts from another variant + Artifacts []ArtifactsConfig `yaml:"artifacts"` // non-standard artifact configuration CommonConfig `yaml:",inline"` } +// Merge takes another VariantConfig and overwrites this struct's fields. +// Artifacts are merged additively. +// func (vc *VariantConfig) Merge(vc2 VariantConfig) { vc.Copies = vc2.Copies vc.Artifacts = append(vc.Artifacts, vc2.Artifacts...) vc.CommonConfig.Merge(vc2.CommonConfig) } +// InstructionsForPhase injects build instructions related to artifact +// copying, volume definition or copying of application files, and all common +// configuration. +// +// PhaseInstall +// +// If VariantConfig.Copies is not set, either copy in application files or +// define a shared volume. Otherwise, delegate to +// ArtifactsConfig.InstructionsForPhase. +// func (vc *VariantConfig) InstructionsForPhase(phase build.Phase) []build.Instruction { instructions := vc.CommonConfig.InstructionsForPhase(phase) ainstructions := []build.Instruction{} @@ -41,6 +56,9 @@ func (vc *VariantConfig) InstructionsForPhase(phase build.Phase) []build.Instruc return instructions } +// VariantDependencies returns all unique names of other variants that are +// referenced in the VariantConfig.Artifacts configuration. +// func (vc *VariantConfig) VariantDependencies() []string { // get unique set of variant dependencies based on artifacts existing := map[string]bool{} |