5
5
6
6
"github.com/golang/glog"
7
7
8
- "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
9
-
10
8
deployapi "github.com/openshift/origin/pkg/deploy/api"
11
9
imageapi "github.com/openshift/origin/pkg/image/api"
12
10
)
@@ -26,62 +24,63 @@ func (e fatalError) Error() string { return "fatal error handling imageRepositor
26
24
27
25
// Handle processes image change triggers associated with imageRepo.
28
26
func (c * ImageChangeController ) Handle (imageRepo * imageapi.ImageRepository ) error {
29
- configsToGenerate := []* deployapi.DeploymentConfig {}
30
- firedTriggersForConfig := make (map [string ][]deployapi.DeploymentTriggerImageChangeParams )
31
-
32
27
configs , err := c .deploymentConfigClient .listDeploymentConfigs ()
33
28
if err != nil {
34
29
return fmt .Errorf ("couldn't get list of deploymentConfigs while handling imageRepo %s: %v" , labelForRepo (imageRepo ), err )
35
30
}
36
31
32
+ // Find any configs which should be updated based on the new image state
33
+ configsToUpdate := map [string ]* deployapi.DeploymentConfig {}
37
34
for _ , config := range configs {
38
35
glog .V (4 ).Infof ("Detecting changed images for deploymentConfig %s" , labelFor (config ))
39
36
40
- // Extract relevant triggers for this imageRepo for this config
41
- triggersForConfig := []deployapi.DeploymentTriggerImageChangeParams {}
42
37
for _ , trigger := range config .Triggers {
43
- if trigger .Type != deployapi .DeploymentTriggerOnImageChange ||
44
- ! trigger .ImageChangeParams .Automatic {
38
+ params := trigger .ImageChangeParams
39
+
40
+ // Only automatic image change triggers should fire
41
+ if trigger .Type != deployapi .DeploymentTriggerOnImageChange || ! params .Automatic {
45
42
continue
46
43
}
47
- if triggerMatchesImage (config , trigger .ImageChangeParams , imageRepo ) {
48
- glog .V (4 ).Infof ("Found matching %s trigger for deploymentConfig %s: %#v" , trigger .Type , labelFor (config ), trigger .ImageChangeParams )
49
- triggersForConfig = append (triggersForConfig , * trigger .ImageChangeParams )
44
+
45
+ // Check if the image repo matches the trigger
46
+ if ! triggerMatchesImage (config , params , imageRepo ) {
47
+ continue
50
48
}
51
- }
52
49
53
- for _ , params := range triggersForConfig {
54
- glog .V (4 ).Infof ("Processing image triggers for deploymentConfig %s" , labelFor (config ))
55
- containerNames := util .NewStringSet (params .ContainerNames ... )
56
- for _ , container := range config .Template .ControllerTemplate .Template .Spec .Containers {
57
- if ! containerNames .Has (container .Name ) {
58
- continue
59
- }
60
-
61
- tagChanged , last , next , err := imageapi .DiffTag (params .Tag , container .Image , imageRepo )
62
- if err != nil {
63
- glog .V (4 ).Infof ("Couldn't detect tag update for container %s in config %s: %v" , container .Name , labelFor (config ), err )
64
- continue
65
- }
66
-
67
- if ! tagChanged {
68
- continue
69
- }
70
-
71
- glog .V (4 ).Infof ("Container %s in config %s: image id changed from %q to %q; regenerating config" , container .Name , labelFor (config ), last , next )
72
- configsToGenerate = append (configsToGenerate , config )
73
- firedTriggersForConfig [config .Name ] = append (firedTriggersForConfig [config .Name ], params )
50
+ // Find the latest tag event for the trigger tag
51
+ latestEvent , err := imageapi .LatestTaggedImage (imageRepo , params .Tag )
52
+ if err != nil {
53
+ glog .V (4 ).Infof ("Couldn't find latest tag event for tag %s in imageRepo %s: %s" , params .Tag , labelForRepo (imageRepo ), err )
54
+ continue
55
+ }
56
+
57
+ // If the tag event doesn't have an image ID yet, we can't determine
58
+ // whether there was really a change
59
+ if len (latestEvent .Image ) == 0 {
60
+ glog .V (4 ).Infof ("Won't trigger for imageRepo %s because it has no image ID" , labelForRepo (imageRepo ))
61
+ continue
74
62
}
63
+
64
+ // Ensure a change occured
65
+ if latestEvent .Image == params .Status .LastTriggeredImage {
66
+ continue
67
+ }
68
+
69
+ // Mark the config for regeneration
70
+ configsToUpdate [config .Name ] = config
75
71
}
76
72
}
77
73
74
+ // Attempt to regenerate all configs which may contain image updates
78
75
anyFailed := false
79
- for _ , config := range configsToGenerate {
80
- err := c .regenerate (imageRepo , config , firedTriggersForConfig [ config . Name ] )
76
+ for _ , config := range configsToUpdate {
77
+ err := c .regenerate (config )
81
78
if err != nil {
82
79
anyFailed = true
80
+ glog .Infof ("couldn't regenerate depoymentConfig %s: %s" , labelFor (config ), err )
83
81
continue
84
82
}
83
+
85
84
glog .V (4 ).Infof ("Updated deploymentConfig %s in response to image change trigger" , labelFor (config ))
86
85
}
87
86
@@ -97,64 +96,40 @@ func (c *ImageChangeController) Handle(imageRepo *imageapi.ImageRepository) erro
97
96
// When matching:
98
97
// - The trigger From field is preferred over the deprecated RepositoryName field.
99
98
// - The namespace of the trigger is preferred over the config's namespace.
100
- func triggerMatchesImage (config * deployapi.DeploymentConfig , trigger * deployapi.DeploymentTriggerImageChangeParams , repo * imageapi.ImageRepository ) bool {
101
- if len (trigger .From .Name ) > 0 {
102
- namespace := trigger .From .Namespace
99
+ func triggerMatchesImage (config * deployapi.DeploymentConfig , params * deployapi.DeploymentTriggerImageChangeParams , repo * imageapi.ImageRepository ) bool {
100
+ if len (params .From .Name ) > 0 {
101
+ namespace := params .From .Namespace
103
102
if len (namespace ) == 0 {
104
103
namespace = config .Namespace
105
104
}
106
105
107
- return repo .Namespace == namespace && repo .Name == trigger .From .Name
106
+ return repo .Namespace == namespace && repo .Name == params .From .Name
108
107
}
109
108
110
109
// This is an invalid state (as one of From.Name or RepositoryName is required), but
111
110
// account for it anyway.
112
- if len (trigger .RepositoryName ) == 0 {
111
+ if len (params .RepositoryName ) == 0 {
113
112
return false
114
113
}
115
114
116
115
// If the repo's repository information isn't yet available, we can't assume it'll match.
117
116
return len (repo .Status .DockerImageRepository ) > 0 &&
118
- trigger .RepositoryName == repo .Status .DockerImageRepository
117
+ params .RepositoryName == repo .Status .DockerImageRepository
119
118
}
120
119
121
- func (c * ImageChangeController ) regenerate (imageRepo * imageapi.ImageRepository , config * deployapi.DeploymentConfig , triggers []deployapi.DeploymentTriggerImageChangeParams ) error {
120
+ // regenerate calls the generator to get a new config. If the newly generated
121
+ // config's version is newer, update the old config to be the new config.
122
+ // Otherwise do nothing.
123
+ func (c * ImageChangeController ) regenerate (config * deployapi.DeploymentConfig ) error {
122
124
// Get a regenerated config which includes the new image repo references
123
125
newConfig , err := c .deploymentConfigClient .generateDeploymentConfig (config .Namespace , config .Name )
124
126
if err != nil {
125
127
return fmt .Errorf ("error generating new version of deploymentConfig %s: %v" , labelFor (config ), err )
126
128
}
127
129
128
- // Update the deployment config with the trigger that resulted in the new config
129
- causes := []* deployapi.DeploymentCause {}
130
- for _ , trigger := range triggers {
131
- repoName := trigger .RepositoryName
132
-
133
- if len (repoName ) == 0 {
134
- if len (imageRepo .Status .DockerImageRepository ) == 0 {
135
- // If the trigger relies on a image repo reference, and we don't know what docker repo
136
- // it points at, we can't build a cause for the reference yet.
137
- continue
138
- }
139
-
140
- latest , err := imageapi .LatestTaggedImage (imageRepo , trigger .Tag )
141
- if err != nil {
142
- return fmt .Errorf ("error generating new version of deploymentConfig: %s: %s" , labelFor (config ), err )
143
- }
144
- repoName = latest .DockerImageReference
145
- }
146
-
147
- causes = append (causes ,
148
- & deployapi.DeploymentCause {
149
- Type : deployapi .DeploymentTriggerOnImageChange ,
150
- ImageTrigger : & deployapi.DeploymentCauseImageTrigger {
151
- RepositoryName : repoName ,
152
- Tag : trigger .Tag ,
153
- },
154
- })
155
- }
156
- newConfig .Details = & deployapi.DeploymentDetails {
157
- Causes : causes ,
130
+ // No update occured
131
+ if config .LatestVersion == newConfig .LatestVersion {
132
+ return nil
158
133
}
159
134
160
135
// Persist the new config
@@ -163,6 +138,7 @@ func (c *ImageChangeController) regenerate(imageRepo *imageapi.ImageRepository,
163
138
return err
164
139
}
165
140
141
+ glog .Infof ("Regenerated depoymentConfig %s for image updates" , labelFor (config ))
166
142
return nil
167
143
}
168
144
0 commit comments