blob: c8c273091ac13a04a4e7b602357f4c98d339c761 [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
giolekvab1f19ee2020-05-16 11:31:20 +040026 Schema Schema
27 Triggers Triggers
28 Actions Actions
giolekva1c0372c2020-05-16 21:18:59 +040029 Init Init
giolekvaa4a153b2020-05-12 11:49:53 +040030 Yamls []string
31}
32
33func HelmChartFromDir(chartDir string) (*HelmChart, error) {
34 var chart HelmChart
35 chart.chartDir = chartDir
giolekvab1f19ee2020-05-16 11:31:20 +040036 err := FromYamlFile(path.Join(chartDir, "Chart.yaml"), &chart.Chart)
giolekvaa4a153b2020-05-12 11:49:53 +040037 if err != nil {
38 return nil, err
39 }
giolekvab1f19ee2020-05-16 11:31:20 +040040 err = FromYamlFile(path.Join(chartDir, "Schema.yaml"), &chart.Schema)
giolekva06eb1642020-05-13 15:32:59 +040041 if err != nil && !os.IsNotExist(err) {
giolekvaa4a153b2020-05-12 11:49:53 +040042 return nil, err
43 }
giolekvab1f19ee2020-05-16 11:31:20 +040044 err = FromYamlFile(path.Join(chartDir, "Triggers.yaml"), &chart.Triggers)
giolekva6d464592020-05-13 20:12:18 +040045 if err != nil && !os.IsNotExist(err) {
46 return nil, err
47 }
giolekvab1f19ee2020-05-16 11:31:20 +040048 err = FromYamlFile(path.Join(chartDir, "Actions.yaml"), &chart.Actions)
49 if err != nil && !os.IsNotExist(err) {
50 return nil, err
51 }
giolekva1c0372c2020-05-16 21:18:59 +040052 err = FromYamlFile(path.Join(chartDir, "Init.yaml"), &chart.Init)
53 if err != nil && !os.IsNotExist(err) {
54 return nil, err
55 }
giolekvaa4a153b2020-05-12 11:49:53 +040056 return &chart, nil
57}
58
59func HelmChartFromTar(chartTar string) (*HelmChart, error) {
60 if !strings.HasSuffix(chartTar, ".tar.gz") {
61 return nil, errors.New("Expected .tar.gz file")
62 }
63 dir := filepath.Dir(chartTar)
64 archive := filepath.Base(chartTar)
giolekvaebea5822020-05-12 20:52:19 +040065 if err := syscall.Chdir(dir); err != nil {
giolekvaa4a153b2020-05-12 11:49:53 +040066 return nil, err
67 }
giolekvaebea5822020-05-12 20:52:19 +040068 cmd := exec.Command("tar", "-xvf", archive)
69 var stdout strings.Builder
70 var stderr strings.Builder
71 cmd.Stdout = &stdout
72 cmd.Stderr = &stderr
73 if err := cmd.Run(); err != nil {
giolekvaebea5822020-05-12 20:52:19 +040074 return nil, errors.New(stderr.String())
75 }
76 glog.Info(stdout.String())
77 glog.Info(dir)
78 return HelmChartFromDir(dir)
giolekvaa4a153b2020-05-12 11:49:53 +040079}
80
81func (h *HelmChart) Install(
82 helmBin string,
83 values map[string]string) error {
84 namespace := fmt.Sprintf("app-%s", h.Chart.Name)
85 cmd := generateHelmInstallCmd(helmBin, h.chartDir, namespace, values)
86 glog.Info(cmd.String())
87 var stdout strings.Builder
88 var stderr strings.Builder
89 cmd.Stdout = &stdout
90 cmd.Stderr = &stderr
91 err := cmd.Run()
92 if err != nil {
93 return errors.New(stderr.String())
94 }
95 glog.Info(stdout.String())
96 return nil
97}
98
99func generateHelmInstallCmd(
100 helmBin string,
101 archive string,
102 namespace string,
103 values map[string]string) *exec.Cmd {
104 cmd := exec.Command(helmBin)
105 cmd.Args = append(cmd.Args, "install")
106 cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", namespace))
107 cmd.Args = append(cmd.Args, "--generate-name")
108 cmd.Args = append(cmd.Args, fmt.Sprintf("%s", archive))
109 // TODO(giolekva): validate values
110 for key, value := range values {
111 cmd.Args = append(cmd.Args, fmt.Sprintf("--set=%s=%s", key, value))
112 }
113 return cmd
114}
115
116func ChartFromYaml(str string) (*Chart, error) {
117 var s Chart
118 err := yaml.Unmarshal([]byte(str), &s)
119 if err != nil {
120 return nil, err
121 }
122 return &s, nil
123}
124
125func ReadChart(chartFile string) (*Chart, error) {
126 f, err := os.Open(chartFile)
127 if err != nil {
128 return nil, err
129 }
130 defer f.Close()
131 b, err := ioutil.ReadAll(f)
132 if err != nil {
133 return nil, err
134 }
135 return ChartFromYaml(string(b))
136}