blob: 9fdf4eda0519785b2315e1ad422fcd2793578b8b [file] [log] [blame]
giolekvaa4a153b2020-05-12 11:49:53 +04001package appmanager
2
3import (
4 "errors"
5 "fmt"
6 "io/ioutil"
7 "os"
8 "os/exec"
9 "path"
10 "path/filepath"
11 "strings"
giolekvaebea5822020-05-12 20:52:19 +040012 "syscall"
giolekvaa4a153b2020-05-12 11:49:53 +040013
14 "github.com/golang/glog"
15 "gopkg.in/yaml.v2"
16)
17
18type Chart struct {
19 Name string `yaml:"name"`
giolekva30036e72020-05-13 22:00:40 +040020 Type string `yaml:"type"`
giolekvaa4a153b2020-05-12 11:49:53 +040021}
22
23type HelmChart struct {
24 Chart
25 chartDir string
26 Schema *Schema
giolekva6d464592020-05-13 20:12:18 +040027 Triggers *Triggers
giolekvaa4a153b2020-05-12 11:49:53 +040028 Yamls []string
29}
30
31func HelmChartFromDir(chartDir string) (*HelmChart, error) {
32 var chart HelmChart
33 chart.chartDir = chartDir
34 c, err := ReadChart(path.Join(chartDir, "Chart.yaml"))
35 if err != nil {
36 return nil, err
37 }
38 chart.Chart = *c
39 schema, err := ReadSchema(path.Join(chartDir, "Schema.yaml"))
giolekva06eb1642020-05-13 15:32:59 +040040 if err != nil && !os.IsNotExist(err) {
giolekvaa4a153b2020-05-12 11:49:53 +040041 return nil, err
42 }
43 chart.Schema = schema
giolekva6d464592020-05-13 20:12:18 +040044 triggers, err := ReadTriggers(path.Join(chartDir, "Triggers.yaml"))
45 if err != nil && !os.IsNotExist(err) {
46 return nil, err
47 }
48 chart.Triggers = triggers
giolekvaa4a153b2020-05-12 11:49:53 +040049 return &chart, nil
50}
51
52func HelmChartFromTar(chartTar string) (*HelmChart, error) {
53 if !strings.HasSuffix(chartTar, ".tar.gz") {
54 return nil, errors.New("Expected .tar.gz file")
55 }
56 dir := filepath.Dir(chartTar)
57 archive := filepath.Base(chartTar)
giolekvaebea5822020-05-12 20:52:19 +040058 if err := syscall.Chdir(dir); err != nil {
giolekvaa4a153b2020-05-12 11:49:53 +040059 return nil, err
60 }
giolekvaebea5822020-05-12 20:52:19 +040061 cmd := exec.Command("tar", "-xvf", archive)
62 var stdout strings.Builder
63 var stderr strings.Builder
64 cmd.Stdout = &stdout
65 cmd.Stderr = &stderr
66 if err := cmd.Run(); err != nil {
giolekvaebea5822020-05-12 20:52:19 +040067 return nil, errors.New(stderr.String())
68 }
69 glog.Info(stdout.String())
70 glog.Info(dir)
71 return HelmChartFromDir(dir)
giolekvaa4a153b2020-05-12 11:49:53 +040072}
73
74func (h *HelmChart) Install(
75 helmBin string,
76 values map[string]string) error {
77 namespace := fmt.Sprintf("app-%s", h.Chart.Name)
78 cmd := generateHelmInstallCmd(helmBin, h.chartDir, namespace, values)
79 glog.Info(cmd.String())
80 var stdout strings.Builder
81 var stderr strings.Builder
82 cmd.Stdout = &stdout
83 cmd.Stderr = &stderr
84 err := cmd.Run()
85 if err != nil {
86 return errors.New(stderr.String())
87 }
88 glog.Info(stdout.String())
89 return nil
90}
91
92func generateHelmInstallCmd(
93 helmBin string,
94 archive string,
95 namespace string,
96 values map[string]string) *exec.Cmd {
97 cmd := exec.Command(helmBin)
98 cmd.Args = append(cmd.Args, "install")
99 cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", namespace))
100 cmd.Args = append(cmd.Args, "--generate-name")
101 cmd.Args = append(cmd.Args, fmt.Sprintf("%s", archive))
102 // TODO(giolekva): validate values
103 for key, value := range values {
104 cmd.Args = append(cmd.Args, fmt.Sprintf("--set=%s=%s", key, value))
105 }
106 return cmd
107}
108
109func ChartFromYaml(str string) (*Chart, error) {
110 var s Chart
111 err := yaml.Unmarshal([]byte(str), &s)
112 if err != nil {
113 return nil, err
114 }
115 return &s, nil
116}
117
118func ReadChart(chartFile string) (*Chart, error) {
119 f, err := os.Open(chartFile)
120 if err != nil {
121 return nil, err
122 }
123 defer f.Close()
124 b, err := ioutil.ReadAll(f)
125 if err != nil {
126 return nil, err
127 }
128 return ChartFromYaml(string(b))
129}