mirror of https://github.com/helm/helm
parent
b5ce6939df
commit
063e37525c
@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
dep "github.com/deis/helm-dm/deploy"
|
||||
"github.com/deis/helm-dm/format"
|
||||
)
|
||||
|
||||
func deploy(cfg *dep.Deployment, dry bool) error {
|
||||
if dry {
|
||||
format.Error("Not implemented: --dry-run")
|
||||
}
|
||||
if cfg.Filename == "" {
|
||||
return errors.New("A filename must be specified. For a tar archive, this is the name of the root template in the archive.")
|
||||
}
|
||||
|
||||
if err := cfg.Commit(); err != nil {
|
||||
format.Error("Failed to commit deployment: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TODO: The concept of property here is really simple. We could definitely get
|
||||
// better about the values we allow. Also, we need some validation on the names.
|
||||
|
||||
var errInvalidProperty = errors.New("property is not in name=value format")
|
||||
|
||||
// parseProperties is a utility for parsing a comma-separated key=value string.
|
||||
func parseProperties(kvstr string) (map[string]interface{}, error) {
|
||||
properties := map[string]interface{}{}
|
||||
|
||||
if len(kvstr) == 0 {
|
||||
return properties, nil
|
||||
}
|
||||
|
||||
pairs := strings.Split(kvstr, ",")
|
||||
for _, p := range pairs {
|
||||
// Allow for "k=v, k=v"
|
||||
p = strings.TrimSpace(p)
|
||||
pair := strings.Split(p, "=")
|
||||
if len(pair) == 1 {
|
||||
return properties, errInvalidProperty
|
||||
}
|
||||
|
||||
// If the value looks int-like, convert it.
|
||||
if i, err := strconv.Atoi(pair[1]); err == nil {
|
||||
properties[pair[0]] = pair[1]
|
||||
} else {
|
||||
properties[pair[0]] = i
|
||||
}
|
||||
}
|
||||
|
||||
return properties, nil
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
package deploy
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/kubernetes/deployment-manager/common"
|
||||
"github.com/kubernetes/deployment-manager/expandybird/expander"
|
||||
"github.com/kubernetes/deployment-manager/registry"
|
||||
)
|
||||
|
||||
type Deployer interface {
|
||||
Commit() error
|
||||
}
|
||||
|
||||
// Deployment describes a deployment of a package.
|
||||
type Deployment struct {
|
||||
// Name is the Deployment name. Autogenerated if empty.
|
||||
Name string
|
||||
// Filename is the filename for the base deployment.
|
||||
Filename string
|
||||
// Imports is a list of imported files.
|
||||
Imports []string
|
||||
// Properties to pass into the template.
|
||||
Properties map[string]interface{}
|
||||
// Input is a file containing templates. It may be os.Stdin.
|
||||
Input *os.File
|
||||
// Repository is the location of the templates.
|
||||
Repository string
|
||||
}
|
||||
|
||||
// Commit prepares the Deployment and then commits it to the remote processor.
|
||||
func (d *Deployment) Commit() error {
|
||||
tpl, err := d.resolveTemplate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If a deployment Name is specified, set that explicitly.
|
||||
if d.Name != "" {
|
||||
tpl.Name = d.Name
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// resolveTemplate resolves what kind of template is being loaded, and then returns the template.
|
||||
func (d *Deployment) resolveTemplate() (*common.Template, error) {
|
||||
// If some input has been specified, read it.
|
||||
if d.Input != nil {
|
||||
// Assume this is a tar archive.
|
||||
tpl, err := expander.NewTemplateFromArchive(d.Filename, d.Input, d.Imports)
|
||||
if err == nil {
|
||||
return tpl, err
|
||||
} else if err != tar.ErrHeader {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If we get here, the file is not a tar archive.
|
||||
if _, err := os.Stdin.Seek(0, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return expander.NewTemplateFromReader(d.Filename, d.Input, d.Imports)
|
||||
}
|
||||
|
||||
// Non-Stdin case
|
||||
if len(d.Imports) > 0 {
|
||||
if t, err := registryType(d.Filename); err != nil {
|
||||
return expander.NewTemplateFromRootTemplate(d.Filename)
|
||||
} else {
|
||||
return buildTemplateFromType(t, d.Repository, d.Properties)
|
||||
}
|
||||
}
|
||||
return expander.NewTemplateFromFileNames(d.Filename, d.Imports)
|
||||
}
|
||||
|
||||
// registryType is a placeholder until registry.ParseType() is merged.
|
||||
func registryType(name string) (*registry.Type, error) {
|
||||
tList := strings.Split(name, ":")
|
||||
if len(tList) != 2 {
|
||||
return nil, errors.New("No version")
|
||||
}
|
||||
|
||||
tt := registry.Type{Version: tList[1]}
|
||||
|
||||
cList := strings.Split(tList[0], "/")
|
||||
|
||||
if len(cList) == 1 {
|
||||
tt.Name = tList[0]
|
||||
} else {
|
||||
tt.Collection = cList[0]
|
||||
tt.Name = cList[1]
|
||||
}
|
||||
return &tt, nil
|
||||
}
|
||||
|
||||
// buildTemplateFromType is a straight lift-n-shift from dm.go.
|
||||
func buildTemplateFromType(t *registry.Type, reg string, props map[string]interface{}) (*common.Template, error) {
|
||||
// Name the deployment after the type name.
|
||||
name := fmt.Sprintf("%s:%s", t.Name, t.Version)
|
||||
git, err := getGitRegistry(reg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gurls, err := git.GetURLs(*t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config := common.Configuration{Resources: []*common.Resource{&common.Resource{
|
||||
Name: name,
|
||||
Type: gurls[0],
|
||||
Properties: props,
|
||||
}}}
|
||||
|
||||
y, err := yaml.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error: %s\ncannot create configuration for deployment: %v\n", err, config)
|
||||
}
|
||||
|
||||
return &common.Template{
|
||||
Name: name,
|
||||
Content: string(y),
|
||||
// No imports, as this is a single type from repository.
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getGitRegistry(reg string) (registry.Registry, error) {
|
||||
s := strings.SplitN(reg, "/", 3)
|
||||
if len(s) < 2 {
|
||||
return nil, fmt.Errorf("invalid template registry: %s", reg)
|
||||
}
|
||||
|
||||
path := ""
|
||||
if len(s) > 2 {
|
||||
path = s[3]
|
||||
}
|
||||
|
||||
if s[0] == "helm" {
|
||||
return registry.NewGithubPackageRegistry(s[0], s[1]), nil
|
||||
} else {
|
||||
return registry.NewGithubRegistry(s[0], s[1], path), nil
|
||||
}
|
||||
}
|
Loading…
Reference in new issue