-
Notifications
You must be signed in to change notification settings - Fork 105
/
app_fetch.go
84 lines (71 loc) · 2.16 KB
/
app_fetch.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
// Copyright 2024 The Carvel Authors.
// SPDX-License-Identifier: Apache-2.0
package pkgrepository
import (
"bytes"
"fmt"
"path"
"strconv"
"time"
"carvel.dev/kapp-controller/pkg/exec"
)
func (a *App) fetch(dstPath string) (string, exec.CmdRunResult) {
if len(a.app.Spec.Fetch) == 0 {
return "", exec.NewCmdRunResultWithErr(fmt.Errorf("Expected at least one fetch option"))
}
var result exec.CmdRunResult
vendir := a.fetchFactory.NewVendir(a.app.Namespace)
// Because vendir doesn't allow placing contents in the vendir root, we
// place all contents in sub dirs. For backwards compatibility, we must
// update dstPath to point to dstPath/0 if there is just one fetch step
for i, fetch := range a.app.Spec.Fetch {
err := vendir.AddDir(fetch, strconv.Itoa(i))
if err != nil {
result.AttachErrorf(fmt.Sprintf("Fetching (%d): ", i)+"%s", err)
return "", result
}
}
conf, err := vendir.ConfigBytes()
if err != nil {
result.AttachErrorf("Fetching: %v", err)
return "", result
}
result = vendir.Run(conf, dstPath, a.cacheID())
// retry if error occurs before reporting failure.
// This is mainly done to support private registry
// authentication for images/bundles since placeholder
// secrets may not be populated in time.
if result.Error != nil && a.HasImageOrImgpkgBundle() {
// Only retrying once resulted in flaky behavior
// for private auth so use 3 iterations.
for i := 0; i < 3; i++ {
// Sleep for 2 seconds to allow secretgen-controller
// to update placeholder secret(s).
time.Sleep(2 * time.Second)
newConf, err := vendir.ConfigBytes()
if err != nil {
result.AttachErrorf("Fetching: %v", err)
return "", result
}
if bytes.Equal(conf, newConf) {
// no secrets/configmaps have changed, no point in retrying
continue
}
result = vendir.Run(newConf, dstPath, a.cacheID())
if result.Error == nil {
break
}
}
if result.Error != nil {
return "", result
}
}
// if only one fetch, update dstPath for backwards compatibility
if len(a.app.Spec.Fetch) == 1 {
dstPath = path.Join(dstPath, "0")
}
return dstPath, result
}
func (a *App) cacheID() string {
return string(a.pkgRepoUID)
}