forked from openshift/origin
/
helpers.go
166 lines (149 loc) · 5.07 KB
/
helpers.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
161
162
163
164
165
166
package apps
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
imageapi "github.com/openshift/origin/pkg/image/apis/image"
)
// DeploymentToPodLogOptions builds a PodLogOptions object out of a DeploymentLogOptions.
// Currently DeploymentLogOptions.Container and DeploymentLogOptions.Previous aren't used
// so they won't be copied to PodLogOptions.
//
// Note that Previous for PodLogOptions is different from Previous for DeploymentLogOptions
// so it shouldn't be included here.
func DeploymentToPodLogOptions(opts *DeploymentLogOptions) *kapi.PodLogOptions {
return &kapi.PodLogOptions{
Follow: opts.Follow,
SinceSeconds: opts.SinceSeconds,
SinceTime: opts.SinceTime,
Timestamps: opts.Timestamps,
TailLines: opts.TailLines,
LimitBytes: opts.LimitBytes,
}
}
// ScaleFromConfig builds a scale resource out of a deployment config.
func ScaleFromConfig(dc *DeploymentConfig) *extensions.Scale {
return &extensions.Scale{
ObjectMeta: metav1.ObjectMeta{
Name: dc.Name,
Namespace: dc.Namespace,
UID: dc.UID,
ResourceVersion: dc.ResourceVersion,
CreationTimestamp: dc.CreationTimestamp,
},
Spec: extensions.ScaleSpec{
Replicas: dc.Spec.Replicas,
},
Status: extensions.ScaleStatus{
Replicas: dc.Status.Replicas,
Selector: &metav1.LabelSelector{
MatchLabels: dc.Spec.Selector,
},
},
}
}
// TemplateImage is a structure for helping a caller iterate over a PodSpec
type TemplateImage struct {
Image string
Ref *imageapi.DockerImageReference
From *kapi.ObjectReference
Container *kapi.Container
}
// templateImageForContainer takes a container and returns a TemplateImage.
func templateImageForContainer(container *kapi.Container, triggerFn TriggeredByFunc) (TemplateImage, error) {
var ref imageapi.DockerImageReference
if trigger, ok := triggerFn(container); ok {
trigger.Image = container.Image
trigger.Container = container
return trigger, nil
}
ref, err := imageapi.ParseDockerImageReference(container.Image)
if err != nil {
return TemplateImage{Image: container.Image, Container: container}, err
}
return TemplateImage{Image: container.Image, Ref: &ref, Container: container}, nil
}
// TemplateImageForContainer locates the requested container in a pod spec, returning information about the
// trigger (if it exists), or an error.
func TemplateImageForContainer(pod *kapi.PodSpec, triggerFn TriggeredByFunc, containerName string) (TemplateImage, error) {
for i := range pod.Containers {
container := &pod.Containers[i]
if container.Name != containerName {
continue
}
return templateImageForContainer(container, triggerFn)
}
for i := range pod.InitContainers {
container := &pod.InitContainers[i]
if container.Name != containerName {
continue
}
return templateImageForContainer(container, triggerFn)
}
return TemplateImage{}, fmt.Errorf("no container %q found", containerName)
}
// eachTemplateImage invokes triggerFn and fn on the provided container.
func eachTemplateImage(container *kapi.Container, triggerFn TriggeredByFunc, fn func(TemplateImage, error)) {
image, err := templateImageForContainer(container, triggerFn)
fn(image, err)
}
// EachTemplateImage iterates a pod spec, looking for triggers that match each container and invoking
// fn with each located image.
func EachTemplateImage(pod *kapi.PodSpec, triggerFn TriggeredByFunc, fn func(TemplateImage, error)) {
for i := range pod.Containers {
eachTemplateImage(&pod.Containers[i], triggerFn, fn)
}
for i := range pod.InitContainers {
eachTemplateImage(&pod.InitContainers[i], triggerFn, fn)
}
}
// EachContainer iterates a pod spec with each container.
func EachContainer(pod *kapi.PodSpec, fn func(*kapi.Container) error) error {
for i := range pod.InitContainers {
container := &pod.InitContainers[i]
if err := fn(container); err != nil {
return err
}
}
for i := range pod.Containers {
container := &pod.Containers[i]
if err := fn(container); err != nil {
return err
}
}
return nil
}
// TriggeredByFunc returns a TemplateImage or error from the provided container
type TriggeredByFunc func(container *kapi.Container) (TemplateImage, bool)
// IgnoreTriggers ignores the triggers
func IgnoreTriggers(container *kapi.Container) (TemplateImage, bool) {
return TemplateImage{}, false
}
// DeploymentConfigHasTrigger returns a function that can identify the image for each container.
func DeploymentConfigHasTrigger(config *DeploymentConfig) TriggeredByFunc {
return func(container *kapi.Container) (TemplateImage, bool) {
for _, trigger := range config.Spec.Triggers {
params := trigger.ImageChangeParams
if params == nil {
continue
}
for _, name := range params.ContainerNames {
if container.Name == name {
if len(params.From.Name) == 0 {
continue
}
from := params.From
if len(from.Namespace) == 0 {
from.Namespace = config.Namespace
}
return TemplateImage{
Image: container.Image,
From: &from,
}, true
}
}
}
return TemplateImage{}, false
}
}