blob: f651fad2f48495543c23d384e12768f36cfbba14 [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"`
20}
21
22type HelmChart struct {
23 Chart
24 chartDir string
25 Schema *Schema
giolekva6d464592020-05-13 20:12:18 +040026 Triggers *Triggers
giolekvaa4a153b2020-05-12 11:49:53 +040027 Yamls []string
28}
29
30func HelmChartFromDir(chartDir string) (*HelmChart, error) {
31 var chart HelmChart
32 chart.chartDir = chartDir
33 c, err := ReadChart(path.Join(chartDir, "Chart.yaml"))
34 if err != nil {
35 return nil, err
36 }
37 chart.Chart = *c
38 schema, err := ReadSchema(path.Join(chartDir, "Schema.yaml"))
giolekva06eb1642020-05-13 15:32:59 +040039 if err != nil && !os.IsNotExist(err) {
giolekvaa4a153b2020-05-12 11:49:53 +040040 return nil, err
41 }
42 chart.Schema = schema
giolekva6d464592020-05-13 20:12:18 +040043 triggers, err := ReadTriggers(path.Join(chartDir, "Triggers.yaml"))
44 if err != nil && !os.IsNotExist(err) {
45 return nil, err
46 }
47 chart.Triggers = triggers
giolekvaa4a153b2020-05-12 11:49:53 +040048 return &chart, nil
49}
50
51func HelmChartFromTar(chartTar string) (*HelmChart, error) {
52 if !strings.HasSuffix(chartTar, ".tar.gz") {
53 return nil, errors.New("Expected .tar.gz file")
54 }
55 dir := filepath.Dir(chartTar)
56 archive := filepath.Base(chartTar)
giolekvaebea5822020-05-12 20:52:19 +040057 if err := syscall.Chdir(dir); err != nil {
giolekvaa4a153b2020-05-12 11:49:53 +040058 return nil, err
59 }
giolekvaebea5822020-05-12 20:52:19 +040060 cmd := exec.Command("tar", "-xvf", archive)
61 var stdout strings.Builder
62 var stderr strings.Builder
63 cmd.Stdout = &stdout
64 cmd.Stderr = &stderr
65 if err := cmd.Run(); err != nil {
giolekvaebea5822020-05-12 20:52:19 +040066 return nil, errors.New(stderr.String())
67 }
68 glog.Info(stdout.String())
69 glog.Info(dir)
70 return HelmChartFromDir(dir)
giolekvaa4a153b2020-05-12 11:49:53 +040071}
72
73func (h *HelmChart) Install(
74 helmBin string,
75 values map[string]string) error {
76 namespace := fmt.Sprintf("app-%s", h.Chart.Name)
77 cmd := generateHelmInstallCmd(helmBin, h.chartDir, namespace, values)
78 glog.Info(cmd.String())
79 var stdout strings.Builder
80 var stderr strings.Builder
81 cmd.Stdout = &stdout
82 cmd.Stderr = &stderr
83 err := cmd.Run()
84 if err != nil {
85 return errors.New(stderr.String())
86 }
87 glog.Info(stdout.String())
88 return nil
89}
90
91func generateHelmInstallCmd(
92 helmBin string,
93 archive string,
94 namespace string,
95 values map[string]string) *exec.Cmd {
96 cmd := exec.Command(helmBin)
97 cmd.Args = append(cmd.Args, "install")
98 cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", namespace))
99 cmd.Args = append(cmd.Args, "--generate-name")
100 cmd.Args = append(cmd.Args, fmt.Sprintf("%s", archive))
101 // TODO(giolekva): validate values
102 for key, value := range values {
103 cmd.Args = append(cmd.Args, fmt.Sprintf("--set=%s=%s", key, value))
104 }
105 return cmd
106}
107
108func ChartFromYaml(str string) (*Chart, error) {
109 var s Chart
110 err := yaml.Unmarshal([]byte(str), &s)
111 if err != nil {
112 return nil, err
113 }
114 return &s, nil
115}
116
117func ReadChart(chartFile string) (*Chart, error) {
118 f, err := os.Open(chartFile)
119 if err != nil {
120 return nil, err
121 }
122 defer f.Close()
123 b, err := ioutil.ReadAll(f)
124 if err != nil {
125 return nil, err
126 }
127 return ChartFromYaml(string(b))
128}