-
Notifications
You must be signed in to change notification settings - Fork 45
/
sync.go
153 lines (126 loc) · 3.6 KB
/
sync.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright 2020 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0
package helmchart
import (
"fmt"
"os"
"path/filepath"
"strings"
ctlconf "carvel.dev/vendir/pkg/vendir/config"
ctlfetch "carvel.dev/vendir/pkg/vendir/fetch"
"sigs.k8s.io/yaml"
)
type Sync struct {
opts ctlconf.DirectoryContentsHelmChart
helmBinary string
refFetcher ctlfetch.RefFetcher
}
func NewSync(opts ctlconf.DirectoryContentsHelmChart,
helmBinary string, refFetcher ctlfetch.RefFetcher) *Sync {
if helmBinary == "" {
helmBinary = "helm"
if opts.HelmVersion == "3" {
helmBinary = "helm3"
}
}
return &Sync{opts, helmBinary, refFetcher}
}
func (t *Sync) Desc() string {
desc := ""
if t.opts.Repository != nil && len(t.opts.Repository.URL) > 0 {
desc += t.opts.Repository.URL + "@"
}
desc += t.opts.Name + ":"
if len(t.opts.Version) > 0 {
desc += t.opts.Version
} else {
desc += "latest"
}
return desc
}
func (t *Sync) Sync(dstPath string, tempArea ctlfetch.TempArea) (ctlconf.LockDirectoryContentsHelmChart, error) {
lockConf := ctlconf.LockDirectoryContentsHelmChart{}
if len(t.opts.Name) == 0 {
return lockConf, fmt.Errorf("Expected non-empty name")
}
chartsDir, err := tempArea.NewTempDir("helm-chart")
if err != nil {
return lockConf, err
}
defer os.RemoveAll(chartsDir)
if t.opts.Repository != nil && strings.HasPrefix(t.opts.Repository.URL, "oci://") {
err = NewOCISource(t.opts, t.helmBinary, t.refFetcher).Fetch(chartsDir, tempArea)
if err != nil {
return lockConf, err
}
} else {
err = NewHTTPSource(t.opts, t.helmBinary, t.refFetcher).Fetch(chartsDir, tempArea)
if err != nil {
return lockConf, err
}
}
chartPath, err := t.findChartDir(chartsDir)
if err != nil {
return lockConf, fmt.Errorf("Finding single helm chart: %s", err)
}
meta, err := t.retrieveChartMeta(chartPath)
if err != nil {
return lockConf, fmt.Errorf("Retrieving helm chart metadata: %s", err)
}
err = ctlfetch.MoveDir(chartPath, dstPath)
if err != nil {
return lockConf, err
}
lockConf.Version = meta.Version
lockConf.AppVersion = meta.AppVersion
return lockConf, nil
}
type chartMeta struct {
AppVersion string
Version string
}
func (t *Sync) retrieveChartMeta(chartPath string) (chartMeta, error) {
var meta chartMeta
bs, err := os.ReadFile(filepath.Join(chartPath, "Chart.yaml"))
if err != nil {
return meta, fmt.Errorf("Reading Chart.yaml: %s", err)
}
err = yaml.Unmarshal(bs, &meta)
if err != nil {
return meta, err
}
if len(meta.Version) == 0 {
return meta, fmt.Errorf("Expected non-empty chart version")
}
return meta, nil
}
func (t *Sync) findChartDir(chartsPath string) (string, error) {
files, err := os.ReadDir(chartsPath)
if err != nil {
return "", err
}
var dirNames []string
for _, file := range files {
if file.IsDir() && !strings.HasSuffix(file.Name(), ".tgz") {
dirNames = append(dirNames, file.Name())
}
}
if len(dirNames) != 1 {
return "", fmt.Errorf("Expected single directory in charts directory, but was: %s", dirNames)
}
return filepath.Join(chartsPath, dirNames[0]), nil
}
func helmEnv(helmHomeDir string) []string {
// Previous discussion around env vars propagation:
// https://github.com/carvel-dev/vendir/issues/164
// Example: without propagating few env vars (e.g. $HOME),
// asdf pkg mgr cannot execute helm binary
// Helm env vars: https://helm.sh/docs/helm/helm/ and https://v2.helm.sh/docs/helm/
return append(os.Environ(), []string{
"HELM_HOME=" + helmHomeDir, // for helm2
"TEMP=" + helmHomeDir,
"HELM_CACHE_HOME=" + helmHomeDir,
"HELM_CONFIG_HOME=" + helmHomeDir,
"HELM_DATA_HOME=" + helmHomeDir,
}...)
}