Save config information in Pulumi.yaml

Instead of having information stored in the checkpoint file, save it
in the Pulumi.yaml file. We introduce a new section `stacks` which
holds information specific to a stack.

Next, we'll support adding configuration information that applies
to *all* stacks for a Program and allow the stack specific config to
overwrite or augment it.
This commit is contained in:
Matt Ellis 2017-10-17 12:28:03 -07:00
parent 906f191e45
commit 9cf9428638
5 changed files with 65 additions and 47 deletions

View file

@ -9,8 +9,6 @@ import (
"github.com/pulumi/pulumi/pkg/pack"
"github.com/pulumi/pulumi/pkg/util/contract"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@ -65,7 +63,7 @@ func parseConfigKey(key string) (tokens.ModuleMember, error) {
// As a convience, we'll treat any key with no delimiter as if:
// <program-name>:config:<key> had been written instead
if !strings.Contains(key, tokens.TokenDelimiter) {
_, pkg, err := getPackage()
pkg, err := getPackage()
if err != nil {
return "", err
}
@ -77,7 +75,7 @@ func parseConfigKey(key string) (tokens.ModuleMember, error) {
}
func prettyKey(key string) string {
_, pkg, err := getPackage()
pkg, err := getPackage()
if err != nil {
return key
}
@ -85,7 +83,7 @@ func prettyKey(key string) string {
return prettyKeyForPackage(key, pkg)
}
func prettyKeyForPackage(key string, pkg pack.Package) string {
func prettyKeyForPackage(key string, pkg *pack.Package) string {
s := key
defaultPrefix := fmt.Sprintf("%s:config:", pkg.Name)
@ -136,43 +134,44 @@ func getConfig(stackName tokens.QName, key tokens.ModuleMember) error {
}
func getConfiguration(stackName tokens.QName) (map[tokens.ModuleMember]string, error) {
target, _, err := getStack(stackName)
pkg, err := getPackage()
if err != nil {
return nil, err
}
contract.Assert(target != nil)
return target.Config, nil
return pkg.Stacks[stackName].Config, nil
}
func deleteConfiguration(stackName tokens.QName, key tokens.ModuleMember) error {
target, snapshot, err := getStack(stackName)
pkg, err := getPackage()
if err != nil {
return err
}
contract.Assert(target != nil)
if target.Config != nil {
delete(target.Config, key)
if pkg.Stacks[stackName].Config != nil {
delete(pkg.Stacks[stackName].Config, key)
}
return saveStack(target, snapshot)
return savePackage(pkg)
}
func setConfiguration(stackName tokens.QName, key tokens.ModuleMember, value string) error {
target, snapshot, err := getStack(stackName)
pkg, err := getPackage()
if err != nil {
return err
}
contract.Assert(target != nil)
if target.Config == nil {
target.Config = make(map[tokens.ModuleMember]string)
if pkg.Stacks == nil {
pkg.Stacks = make(map[tokens.QName]pack.StackInfo)
}
target.Config[key] = value
if pkg.Stacks[stackName].Config == nil {
si := pkg.Stacks[stackName]
si.Config = make(map[tokens.ModuleMember]string)
pkg.Stacks[stackName] = si
}
return saveStack(target, snapshot)
pkg.Stacks[stackName].Config[key] = value
return savePackage(pkg)
}

View file

@ -12,7 +12,7 @@ import (
)
func TestPrettyKeyForPackage(t *testing.T) {
pkg := pack.Package{Name: tokens.PackageName("test-package"), Runtime: "nodejs"}
pkg := &pack.Package{Name: tokens.PackageName("test-package"), Runtime: "nodejs"}
assert.Equal(t, "foo", prettyKeyForPackage("test-package:config:foo", pkg))
assert.Equal(t, "other-package:config:bar", prettyKeyForPackage("other-package:config:bar", pkg))

View file

@ -22,6 +22,18 @@ func (p localStackProvider) GetTarget(name tokens.QName) (*deploy.Target, error)
contract.Require(name != "", "name")
target, _, err := getStack(name)
if err != nil {
return nil, err
}
pkg, err := getPackage()
if err != nil {
return nil, err
}
if pkg.Stacks != nil {
target.Config = pkg.Stacks[name].Config
}
return target, err
}

View file

@ -6,7 +6,6 @@ import (
"io/ioutil"
"os"
"github.com/pulumi/pulumi/pkg/encoding"
"github.com/pulumi/pulumi/pkg/pack"
"github.com/pkg/errors"
@ -103,39 +102,40 @@ func displayEvents(events <-chan engine.Event, done chan bool, debug bool) {
}
}
func getPackage() (string, pack.Package, error) {
func getPackage() (*pack.Package, error) {
pkgPath, err := getPackageFilePath()
if err != nil {
return nil, err
}
pkg, err := pack.Load(pkgPath)
return pkg, err
}
func savePackage(pkg *pack.Package) error {
pkgPath, err := getPackageFilePath()
if err != nil {
return err
}
return pack.Save(pkgPath, pkg)
}
func getPackageFilePath() (string, error) {
dir, err := os.Getwd()
if err != nil {
return "", pack.Package{}, err
return "", err
}
pkgPath, err := workspace.DetectPackage(dir)
if err != nil {
return "", pack.Package{}, err
return "", err
}
if pkgPath == "" {
return "", pack.Package{}, errors.Errorf("could not find Pulumi.yaml, started search in %s", dir)
return "", errors.Errorf("could not find Pulumi.yaml, started search in %s", dir)
}
m, _ := encoding.Detect(pkgPath)
b, err := ioutil.ReadFile(pkgPath)
if err != nil {
return "", pack.Package{}, err
}
var pkg pack.Package
err = m.Unmarshal(b, &pkg)
if err != nil {
return "", pack.Package{}, err
}
err = pkg.Validate()
if err != nil {
return "", pack.Package{}, err
}
return pkgPath, pkg, err
return pkgPath, nil
}

View file

@ -33,9 +33,16 @@ type Package struct {
Analyzers *Analyzers `json:"analyzers,omitempty" yaml:"analyzers,omitempty"` // any analyzers enabled for this project.
Stacks map[tokens.QName]StackInfo `json:"stacks,omitempty" yaml:"stacks,omitempty"` // optional stack specific information.
Doc *diag.Document `json:"-" yaml:"-"` // the document from which this package came.
}
// StackInfo holds stack specific information about a package
type StackInfo struct {
Config map[tokens.ModuleMember]string `json:"config,omitempty" yaml:"config,omitempty"` // optional config.
}
var _ diag.Diagable = (*Package)(nil)
func (pkg *Package) Where() (*diag.Document, *diag.Location) {