blob: 8370b4e2c1de49d164ea182efda40d540b9831a5 [file] [log] [blame]
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +04001package installer
2
3import (
4 "fmt"
giof8843412024-05-22 16:38:05 +04005 "io"
6 "io/fs"
7 "path/filepath"
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +04008
giof8843412024-05-22 16:38:05 +04009 "github.com/giolekva/pcloud/core/installer/soft"
10
11 "github.com/go-git/go-billy/v5/memfs"
12 "github.com/go-git/go-billy/v5/util"
13 "github.com/go-git/go-git/v5"
14 "github.com/go-git/go-git/v5/plumbing"
15 "github.com/go-git/go-git/v5/storage/memory"
Giorgi Lekveishvili7c427602024-01-04 00:13:55 +040016 "helm.sh/helm/v3/pkg/action"
17 "helm.sh/helm/v3/pkg/kube"
18)
19
20type ActionConfigFactory struct {
21 kubeConfigPath string
22}
23
24func NewActionConfigFactory(kubeConfigPath string) ActionConfigFactory {
25 return ActionConfigFactory{kubeConfigPath}
26}
27
28func (f ActionConfigFactory) New(namespace string) (*action.Configuration, error) {
29 config := new(action.Configuration)
30 if err := config.Init(
31 kube.GetConfig(f.kubeConfigPath, "", namespace),
32 namespace,
33 "",
34 func(fmtString string, args ...any) {
35 fmt.Printf(fmtString, args...)
36 fmt.Println()
37 },
38 ); err != nil {
39 return nil, err
40 }
41 return config, nil
42}
giof8843412024-05-22 16:38:05 +040043
44type HelmFetcher interface {
45 Pull(chart HelmChartGitRepo, rfs soft.RepoFS, root string) error
46}
47
gio9877f292024-08-17 15:11:15 +040048type RepoCloner interface {
49 Clone(addr, ref string) (*git.Repository, error)
giof8843412024-05-22 16:38:05 +040050}
51
gio9877f292024-08-17 15:11:15 +040052type cachingRepoCloner struct {
53 cache map[string]*git.Repository
54}
55
56func NewCachingRepoCloner() RepoCloner {
57 return &cachingRepoCloner{make(map[string]*git.Repository)}
58}
59
60func (rc *cachingRepoCloner) Clone(addr, ref string) (*git.Repository, error) {
61 key := fmt.Sprintf("%s:%s", addr, ref)
62 if ret, ok := rc.cache[key]; ok {
63 return ret, nil
64 }
giof8843412024-05-22 16:38:05 +040065 r, err := git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{
gio9877f292024-08-17 15:11:15 +040066 URL: addr,
giof8843412024-05-22 16:38:05 +040067 ReferenceName: plumbing.ReferenceName(ref),
68 SingleBranch: true,
69 Depth: 1,
70 })
71 if err != nil {
gio9877f292024-08-17 15:11:15 +040072 return nil, err
73 }
74 // TODO(gio): enable
75 // rc.cache[key] = r
76 return r, nil
77}
78
79type gitHelmFetcher struct {
80 rc RepoCloner
81}
82
83func NewGitHelmFetcher() *gitHelmFetcher {
84 // TODO(gio): take cloner as an argument
85 return &gitHelmFetcher{NewCachingRepoCloner()}
86}
87
88func (f *gitHelmFetcher) Pull(chart HelmChartGitRepo, rfs soft.RepoFS, root string) error {
89 ref := fmt.Sprintf("refs/heads/%s", chart.Branch)
90 r, err := f.rc.Clone(chart.Address, ref)
91 if err != nil {
giof8843412024-05-22 16:38:05 +040092 return err
93 }
94 wt, err := r.Worktree()
95 if err != nil {
96 return err
97 }
98 wtFS, err := wt.Filesystem.Chroot(chart.Path)
99 if err != nil {
100 return err
101 }
102 return util.Walk(wtFS, "/", func(path string, info fs.FileInfo, err error) error {
103 if info.IsDir() {
104 return nil
105 }
106 inp, err := wtFS.Open(path)
107 if err != nil {
108 return err
109 }
110 out, err := rfs.Writer(filepath.Join(root, path))
111 if err != nil {
112 return err
113 }
114 _, err = io.Copy(out, inp)
115 return err
116 })
117}