blob: 894c96cc333eecc0cb4568b7aaed51d2d34a55d9 [file] [log] [blame]
giolekvaa4a153b2020-05-12 11:49:53 +04001package appmanager
2
3import (
4 "errors"
5 "fmt"
giolekvaa4a153b2020-05-12 11:49:53 +04006 "os"
7 "os/exec"
8 "path"
9 "path/filepath"
10 "strings"
11
12 "github.com/golang/glog"
giolekvaa4a153b2020-05-12 11:49:53 +040013)
14
15type Chart struct {
16 Name string `yaml:"name"`
giolekva30036e72020-05-13 22:00:40 +040017 Type string `yaml:"type"`
giolekvaa4a153b2020-05-12 11:49:53 +040018}
19
20type HelmChart struct {
21 Chart
giolekvadaa85592020-05-16 23:32:02 +040022 Dir string
23 Namespace string
24 Schema Schema
25 Triggers Triggers
26 Actions Actions
27 Init Init
28 Yamls []string
giolekvaa4a153b2020-05-12 11:49:53 +040029}
30
giolekvadaa85592020-05-16 23:32:02 +040031func HelmChartFromDir(dir string) (*HelmChart, error) {
giolekvaa4a153b2020-05-12 11:49:53 +040032 var chart HelmChart
giolekvadaa85592020-05-16 23:32:02 +040033 chart.Dir = dir
34 err := FromYamlFile(path.Join(dir, "Chart.yaml"), &chart.Chart)
giolekvaa4a153b2020-05-12 11:49:53 +040035 if err != nil {
36 return nil, err
37 }
giolekvaa4a153b2020-05-12 11:49:53 +040038 return &chart, nil
39}
40
giolekvadaa85592020-05-16 23:32:02 +040041func (chart *HelmChart) Render(
42 helmBin string,
43 values map[string]string) error {
44 chart.Namespace = fmt.Sprintf("app-%s", chart.Name)
45 renderDir := path.Join(chart.Dir, "__render")
46 if err := chart.renderTemplates(helmBin, values, renderDir); err != nil {
47 return err
48 }
49 if err := os.RemoveAll(path.Join(chart.Dir, "templates")); err != nil {
50 return err
51 }
52 if err := os.Rename(
53 path.Join(renderDir, chart.Name, "templates"),
54 path.Join(chart.Dir, "templates")); err != nil {
55 return err
56 }
57 pcloudDir := path.Join(chart.Dir, "templates/pcloud")
58 err := FromYamlFile(path.Join(pcloudDir, "Schema.yaml"), &chart.Schema)
59 if err != nil && !os.IsNotExist(err) {
60 return err
61 }
62 err = FromYamlFile(path.Join(pcloudDir, "Triggers.yaml"), &chart.Triggers)
63 if err != nil && !os.IsNotExist(err) {
64 return err
65 }
66 err = FromYamlFile(path.Join(pcloudDir, "Actions.yaml"), &chart.Actions)
67 if err != nil && !os.IsNotExist(err) {
68 return err
69 }
70 err = FromYamlFile(path.Join(pcloudDir, "Init.yaml"), &chart.Init)
71 if err != nil && !os.IsNotExist(err) {
72 return err
73 }
74 if err := os.RemoveAll(pcloudDir); err != nil {
75 return err
76 }
77 return nil
78}
79
giolekvaa4a153b2020-05-12 11:49:53 +040080func HelmChartFromTar(chartTar string) (*HelmChart, error) {
81 if !strings.HasSuffix(chartTar, ".tar.gz") {
82 return nil, errors.New("Expected .tar.gz file")
83 }
84 dir := filepath.Dir(chartTar)
85 archive := filepath.Base(chartTar)
giolekvadaa85592020-05-16 23:32:02 +040086 if err := os.Chdir(dir); err != nil {
giolekvaa4a153b2020-05-12 11:49:53 +040087 return nil, err
88 }
giolekvaebea5822020-05-12 20:52:19 +040089 cmd := exec.Command("tar", "-xvf", archive)
90 var stdout strings.Builder
91 var stderr strings.Builder
92 cmd.Stdout = &stdout
93 cmd.Stderr = &stderr
94 if err := cmd.Run(); err != nil {
giolekvaebea5822020-05-12 20:52:19 +040095 return nil, errors.New(stderr.String())
96 }
97 glog.Info(stdout.String())
98 glog.Info(dir)
99 return HelmChartFromDir(dir)
giolekvaa4a153b2020-05-12 11:49:53 +0400100}
101
giolekvadaa85592020-05-16 23:32:02 +0400102func (chart *HelmChart) Install(
103 helmBin string) error {
104 cmd := exec.Command(helmBin)
105 cmd.Args = append(cmd.Args, "install")
106 cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", chart.Namespace))
107 cmd.Args = append(cmd.Args, chart.Name)
108 cmd.Args = append(cmd.Args, fmt.Sprintf("%s", chart.Dir))
109 return runCmd(cmd)
110}
111
112func (chart *HelmChart) renderTemplates(
giolekvaa4a153b2020-05-12 11:49:53 +0400113 helmBin string,
giolekvadaa85592020-05-16 23:32:02 +0400114 values map[string]string,
115 outputDir string) error {
116 cmd := exec.Command(helmBin)
117 cmd.Args = append(cmd.Args, "template")
118 cmd.Args = append(cmd.Args, fmt.Sprintf("--output-dir=%s", outputDir))
119 cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", chart.Namespace))
120 cmd.Args = append(cmd.Args, chart.Name)
121 cmd.Args = append(cmd.Args, chart.Dir)
122 // TODO(giolekva): validate values
123 for key, value := range values {
124 cmd.Args = append(cmd.Args, fmt.Sprintf("--set=%s=%s", key, value))
125 }
126 return runCmd(cmd)
127}
128
129func runCmd(cmd *exec.Cmd) error {
giolekvaa4a153b2020-05-12 11:49:53 +0400130 glog.Info(cmd.String())
131 var stdout strings.Builder
132 var stderr strings.Builder
133 cmd.Stdout = &stdout
134 cmd.Stderr = &stderr
135 err := cmd.Run()
136 if err != nil {
137 return errors.New(stderr.String())
138 }
139 glog.Info(stdout.String())
140 return nil
141}