-
Notifications
You must be signed in to change notification settings - Fork 303
/
k8s_target.go
160 lines (130 loc) · 4.53 KB
/
k8s_target.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
154
155
156
157
158
159
160
package model
import (
"fmt"
"reflect"
"github.com/tilt-dev/tilt/internal/sliceutils"
"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
)
// Specifies how a Pod's state factors into determining whether a resource is ready
type PodReadinessMode string
// Pod readiness isn't applicable to this resource
const PodReadinessNone PodReadinessMode = ""
// Always wait for pods to become ready.
const PodReadinessWait PodReadinessMode = "wait"
// Don't even wait for pods to appear.
const PodReadinessIgnore PodReadinessMode = "ignore"
// wait until the pod has completed successfully
const PodReadinessSucceeded PodReadinessMode = "succeeded"
type K8sTarget struct {
// An apiserver-driven data model for applying Kubernetes YAML.
//
// This will eventually replace K8sTarget. We represent this as an embedded
// struct while we're migrating fields.
v1alpha1.KubernetesApplySpec
Name TargetName
PodReadinessMode PodReadinessMode
// Map configRef -> number of times we (expect to) inject it.
// NOTE(maia): currently this map is only for use in metrics, though someday
// we want a better way of mapping configRefs -> their injection point(s)
// (right now, Tiltfile and Engine have two different ways of finding a
// given image in a k8s entity.
refInjectCounts map[string]int
// zero+ links assoc'd with this resource (to be displayed in UIs,
// in addition to any port forwards/LB endpoints)
Links []Link
// pathDependencies are files required by this target.
//
// For Tiltfile-based, YAML-driven (i.e. `k8s_yaml()`) resources, this is
// NOT used because it's not sufficient to reload the YAML and re-deploy;
// there is a lot of post-Tiltfile-load logic for resource assembly, image
// locator injection, etc. As a result, these resources have their YAML
// files registered as "config files", which cause the Tiltfile to be
// re-evaluated.
pathDependencies []string
localRepos []LocalGitRepo
}
func NewK8sTargetForTesting(yaml string) K8sTarget {
apply := v1alpha1.KubernetesApplySpec{
YAML: yaml,
}
return K8sTarget{KubernetesApplySpec: apply}
}
func (k8s K8sTarget) Empty() bool { return reflect.DeepEqual(k8s, K8sTarget{}) }
func (k8s K8sTarget) DependencyIDs() []TargetID {
result := make([]TargetID, 0, len(k8s.ImageMaps))
for _, im := range k8s.ImageMaps {
result = append(result, TargetID{
Type: TargetTypeImage,
Name: TargetName(im),
})
}
return result
}
func (k8s K8sTarget) RefInjectCounts() map[string]int {
return k8s.refInjectCounts
}
func (k8s K8sTarget) Validate() error {
if k8s.ID().Empty() {
return fmt.Errorf("[Validate] K8s resources missing name:\n%s", k8s.YAML)
}
// TODO(milas): improve error message
if k8s.KubernetesApplySpec.YAML == "" && k8s.KubernetesApplySpec.ApplyCmd == nil {
return fmt.Errorf("[Validate] K8s resources %q missing YAML", k8s.Name)
}
return nil
}
func (k8s K8sTarget) ID() TargetID {
return TargetID{
Type: TargetTypeK8s,
Name: k8s.Name,
}
}
// LocalRepos is part of the WatchableTarget interface.
func (k8s K8sTarget) LocalRepos() []LocalGitRepo {
return k8s.localRepos
}
// Dockerignores is part of the WatchableTarget interface.
func (k8s K8sTarget) Dockerignores() []Dockerignore {
return nil
}
// IgnoredLocalDirectories is part of the WatchableTarget interface.
func (k8s K8sTarget) IgnoredLocalDirectories() []string {
return nil
}
// Dependencies are files required by this target.
//
// Part of the WatchableTarget interface.
func (k8s K8sTarget) Dependencies() []string {
// sorting/de-duping guaranteed by setter
return k8s.pathDependencies
}
// Track which images this depends on.
func (k8s K8sTarget) WithImageDependencies(imageMapDeps []string) K8sTarget {
k8s.ImageMaps = sliceutils.Dedupe(imageMapDeps)
return k8s
}
// WithPathDependencies registers paths that this K8sTarget depends on.
func (k8s K8sTarget) WithPathDependencies(paths []string, localRepos []LocalGitRepo) K8sTarget {
k8s.pathDependencies = sliceutils.DedupedAndSorted(paths)
k8s.localRepos = localRepos
return k8s
}
func (k8s K8sTarget) WithRefInjectCounts(ric map[string]int) K8sTarget {
k8s.refInjectCounts = ric
return k8s
}
var _ TargetSpec = K8sTarget{}
func FilterLiveUpdateOnly(imageMapDeps []string, imageTargets []ImageTarget) []string {
result := make([]string, 0, len(imageMapDeps))
isLiveUpdateOnly := make(map[string]bool, len(imageTargets))
for _, image := range imageTargets {
isLiveUpdateOnly[image.ImageMapName()] = image.IsLiveUpdateOnly
}
for _, im := range imageMapDeps {
if isLiveUpdateOnly[im] {
continue
}
result = append(result, im)
}
return result
}