blob: f651fad2f48495543c23d384e12768f36cfbba14 [file] [log] [blame]
package appmanager
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
"syscall"
"github.com/golang/glog"
"gopkg.in/yaml.v2"
)
type Chart struct {
Name string `yaml:"name"`
}
type HelmChart struct {
Chart
chartDir string
Schema *Schema
Triggers *Triggers
Yamls []string
}
func HelmChartFromDir(chartDir string) (*HelmChart, error) {
var chart HelmChart
chart.chartDir = chartDir
c, err := ReadChart(path.Join(chartDir, "Chart.yaml"))
if err != nil {
return nil, err
}
chart.Chart = *c
schema, err := ReadSchema(path.Join(chartDir, "Schema.yaml"))
if err != nil && !os.IsNotExist(err) {
return nil, err
}
chart.Schema = schema
triggers, err := ReadTriggers(path.Join(chartDir, "Triggers.yaml"))
if err != nil && !os.IsNotExist(err) {
return nil, err
}
chart.Triggers = triggers
return &chart, nil
}
func HelmChartFromTar(chartTar string) (*HelmChart, error) {
if !strings.HasSuffix(chartTar, ".tar.gz") {
return nil, errors.New("Expected .tar.gz file")
}
dir := filepath.Dir(chartTar)
archive := filepath.Base(chartTar)
if err := syscall.Chdir(dir); err != nil {
return nil, err
}
cmd := exec.Command("tar", "-xvf", archive)
var stdout strings.Builder
var stderr strings.Builder
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return nil, errors.New(stderr.String())
}
glog.Info(stdout.String())
glog.Info(dir)
return HelmChartFromDir(dir)
}
func (h *HelmChart) Install(
helmBin string,
values map[string]string) error {
namespace := fmt.Sprintf("app-%s", h.Chart.Name)
cmd := generateHelmInstallCmd(helmBin, h.chartDir, namespace, values)
glog.Info(cmd.String())
var stdout strings.Builder
var stderr strings.Builder
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
return errors.New(stderr.String())
}
glog.Info(stdout.String())
return nil
}
func generateHelmInstallCmd(
helmBin string,
archive string,
namespace string,
values map[string]string) *exec.Cmd {
cmd := exec.Command(helmBin)
cmd.Args = append(cmd.Args, "install")
cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", namespace))
cmd.Args = append(cmd.Args, "--generate-name")
cmd.Args = append(cmd.Args, fmt.Sprintf("%s", archive))
// TODO(giolekva): validate values
for key, value := range values {
cmd.Args = append(cmd.Args, fmt.Sprintf("--set=%s=%s", key, value))
}
return cmd
}
func ChartFromYaml(str string) (*Chart, error) {
var s Chart
err := yaml.Unmarshal([]byte(str), &s)
if err != nil {
return nil, err
}
return &s, nil
}
func ReadChart(chartFile string) (*Chart, error) {
f, err := os.Open(chartFile)
if err != nil {
return nil, err
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
return ChartFromYaml(string(b))
}