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