Made helm client & expandyservice build

pull/390/head
Dave Cunningham 10 years ago committed by jackgr
parent 358a8ed634
commit 36e16b1e6b

@ -19,8 +19,8 @@ package expander
import (
"bytes"
"fmt"
"encoding/json"
"log"
"os"
"os/exec"
"github.com/ghodss/yaml"
@ -119,9 +119,29 @@ func (eResponse *ExpansionResponse) Unmarshal() (*ExpansionResult, error) {
// ExpandTemplate passes the given configuration to the expander and returns the
// expanded configuration as a string on success.
func (e *expander) ExpandTemplate(template *common.Template) (string, error) {
chartInv := template.ChartInvocation
chart := template.Chart
if chart.Expander.Name != "Expandybird" {
message := fmt.Sprintf("Expandybird cannot do this kind of expansion: ", chart.Expander)
return "", fmt.Errorf("error expanding template %s: %s", chartInv.Name, message)
}
if e.ExpansionBinary == "" {
message := fmt.Sprintf("expansion binary cannot be empty")
return "", fmt.Errorf("error expanding template %s: %s", template.Name, message)
return "", fmt.Errorf("error expanding chart %s: %s", chartInv.Name, message)
}
if len(chart.Files) != 1 {
message := fmt.Sprintf("Expandybird can only process a chart containing 1 file, got %d", len(chart.Files))
return "", fmt.Errorf("error expanding template %s: %s", chartInv.Name, message)
}
entrypoint_file := chart.Files[0]
if entrypoint_file.Path != chart.Expander.Entrypoint {
message := fmt.Sprintf("The entrypoint in the chart.yaml canont be found %s", chart.Expander.Entrypoint)
return "", fmt.Errorf("error expanding template %s: %s", chartInv.Name, message)
}
// Those are automatically increasing buffers, so writing arbitrary large
@ -129,20 +149,36 @@ func (e *expander) ExpandTemplate(template *common.Template) (string, error) {
var stdout bytes.Buffer
var stderr bytes.Buffer
// Now we convert the new chart representation into the form that classic Expandybird takes.
chartInvJson, err := json.Marshal(chartInv)
if err != nil {
return "", fmt.Errorf("error marshalling chart invocation %s: %s", chartInv.Name, err)
}
content := "{ \"resources\": [" + string(chartInvJson) + "] }"
cmd := &exec.Cmd{
Path: e.ExpansionBinary,
// Note, that binary name still has to be passed argv[0].
Args: []string{e.ExpansionBinary, template.Content},
Args: []string{e.ExpansionBinary, content},
// TODO(vagababov): figure out whether do we even need "PROJECT" and
// "DEPLOYMENT_NAME" variables here.
Env: append(os.Environ(), "PROJECT="+template.Name, "DEPLOYMENT_NAME="+template.Name),
// [dcunnin]: Assuming we won't need this, at least for now.
// Env: append(os.Environ(), "PROJECT="+chartInv.Name, "DEPLOYMENT_NAME="+chartInv.Name),
Stdout: &stdout,
Stderr: &stderr,
}
for _, imp := range template.Imports {
cmd.Args = append(cmd.Args, imp.Name, imp.Path, imp.Content)
// Add entrypoint file (currently only 1 is supported).
cmd.Args = append(cmd.Args, chart.Name, entrypoint_file.Path, entrypoint_file.Content)
// Add schema file
schema_name := chart.Name + ".schema"
schemaJson, err := json.Marshal(chart.Schema)
if err != nil {
return "", fmt.Errorf("error marshalling schema %s: %s", chartInv.Name, err)
}
cmd.Args = append(cmd.Args, schema_name, schema_name, string(schemaJson))
if err := cmd.Start(); err != nil {
log.Printf("error starting expansion process: %s", err)
@ -154,7 +190,7 @@ func (e *expander) ExpandTemplate(template *common.Template) (string, error) {
log.Printf("Expansion process: pid: %d SysTime: %v UserTime: %v", cmd.ProcessState.Pid(),
cmd.ProcessState.SystemTime(), cmd.ProcessState.UserTime())
if stderr.String() != "" {
return "", fmt.Errorf("error expanding template %s: %s", template.Name, stderr.String())
return "", fmt.Errorf("error expanding chart %s: %s", chartInv.Name, stderr.String())
}
return stdout.String(), nil

@ -17,6 +17,7 @@ limitations under the License.
package main
import (
"fmt"
"io/ioutil"
"os"
@ -55,40 +56,29 @@ func deployCmd() cli.Command {
func deploy(c *cli.Context) error {
// If there is a configuration file, use it.
cfg := &common.Configuration{}
if c.String("config") != "" {
if err := loadConfig(cfg, c.String("config")); err != nil {
return err
}
} else {
cfg.Resources = []*common.Resource{
{
res := &common.Resource{
// By default
Properties: map[string]interface{}{},
},
}
}
// If there is a chart specified on the commandline, override the config
// file with it.
args := c.Args()
if len(args) > 0 {
cname := args[0]
if isLocalChart(cname) {
// If we get here, we need to first package then upload the chart.
loc, err := doUpload(cname, "", c)
if c.String("config") != "" {
// If there is a configuration file, use it.
err := loadConfig(c.String("config"), &res.Properties);
if err != nil {
return err
}
cfg.Resources[0].Name = loc
} else {
cfg.Resources[0].Type = cname
}
args := c.Args()
if len(args) == 0 {
return fmt.Errorf("Need chart name on commandline")
}
res.Type = args[0]
// Override the name if one is passed in.
if name := c.String("name"); len(name) > 0 {
cfg.Resources[0].Name = name
res.Name = name
} else {
return fmt.Errorf("Need deployed name on commandline")
}
if props, err := parseProperties(c.String("properties")); err != nil {
@ -98,11 +88,11 @@ func deploy(c *cli.Context) error {
// knowing which resource the properties are supposed to be part
// of.
for n, v := range props {
cfg.Resources[0].Properties[n] = v
res.Properties[n] = v
}
}
return NewClient(c).PostDeployment(cfg.Resources[0].Name, cfg)
return NewClient(c).PostDeployment(res)
}
// isLocalChart returns true if the given path can be statted.
@ -111,11 +101,11 @@ func isLocalChart(path string) bool {
return err == nil
}
// loadConfig loads a file into a common.Configuration.
func loadConfig(c *common.Configuration, filename string) error {
// loadConfig loads chart arguments into c
func loadConfig(filename string, dest *map[string]interface{}) error {
data, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
return yaml.Unmarshal(data, c)
return yaml.Unmarshal(data, dest)
}

@ -192,3 +192,39 @@ func (e *HTTPError) Error() string {
func (e *HTTPError) String() string {
return e.Error()
}
// GetDeployment retrieves the supplied deployment
func (c *Client) GetDeployment(name string) (*common.Deployment, error) {
var deployment *common.Deployment
if err := c.CallService(fancypath.Join("deployments", name), "GET", "get deployment", &deployment, nil); err != nil {
return nil, err
}
return deployment, nil
}
// DeleteDeployment deletes the supplied deployment
func (c *Client) DeleteDeployment(name string) (*common.Deployment, error) {
var deployment *common.Deployment
if err := c.CallService(filepath.Join("deployments", name), "DELETE", "delete deployment", &deployment, nil); err != nil {
return nil, err
}
return deployment, nil
}
// PostDeployment posts a deployment object to the manager service.
func (c *Client) PostDeployment(res *common.Resource) error {
// This is a stop-gap until we get this API cleaned up.
t := common.Template{
ChartInvocation: res,
}
data, err := json.Marshal(t)
if err != nil {
return err
}
var out struct{}
b := bytes.NewBuffer(data)
return c.CallService("/deployments", "POST", "post deployment", &out, b)
}

Loading…
Cancel
Save