forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
basic_deployment_controller.go
139 lines (114 loc) · 5.63 KB
/
basic_deployment_controller.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
package controller
import (
"github.com/golang/glog"
kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
deployapi "github.com/openshift/origin/pkg/deploy/api"
)
// BasicDeploymentController implements the DeploymentStrategyTypeBasic deployment strategy. Its behavior
// is to create new replication controllers as defined on a Deployment, and delete any previously existing
// replication controllers for the same DeploymentConfig associated with the deployment.
type BasicDeploymentController struct {
DeploymentUpdater bdcDeploymentUpdater
ReplicationControllerClient bdcReplicationControllerClient
NextDeployment func() *deployapi.Deployment
}
type bdcDeploymentUpdater interface {
UpdateDeployment(ctx kapi.Context, deployment *deployapi.Deployment) (*deployapi.Deployment, error)
}
type bdcReplicationControllerClient interface {
ListReplicationControllers(ctx kapi.Context, selector labels.Selector) (*kapi.ReplicationControllerList, error)
GetReplicationController(ctx kapi.Context, id string) (*kapi.ReplicationController, error)
CreateReplicationController(ctx kapi.Context, ctrl *kapi.ReplicationController) (*kapi.ReplicationController, error)
UpdateReplicationController(ctx kapi.Context, ctrl *kapi.ReplicationController) (*kapi.ReplicationController, error)
DeleteReplicationController(ctx kapi.Context, id string) error
}
func (dc *BasicDeploymentController) Run() {
go util.Forever(func() { dc.HandleDeployment() }, 0)
}
// HandleDeployment executes a single Deployment. It's assumed that the strategy of the deployment is
// DeploymentStrategyTypeBasic.
func (dc *BasicDeploymentController) HandleDeployment() error {
deployment := dc.NextDeployment()
if deployment.Strategy.Type != deployapi.DeploymentStrategyTypeBasic {
glog.V(4).Infof("Ignoring deployment %s due to incompatible strategy type %s", deployment.ID, deployment.Strategy)
return nil
}
ctx := kapi.WithNamespace(kapi.NewContext(), deployment.Namespace)
nextStatus := deployment.Status
switch deployment.Status {
case deployapi.DeploymentStatusNew:
nextStatus = dc.handleNew(ctx, deployment)
}
// persist any status change
if deployment.Status != nextStatus {
deployment.Status = nextStatus
glog.V(4).Infof("Saving deployment %v status: %v", deployment.ID, deployment.Status)
if _, err := dc.DeploymentUpdater.UpdateDeployment(ctx, deployment); err != nil {
glog.V(2).Infof("Received error while saving deployment %v: %v", deployment.ID, err)
return err
}
}
return nil
}
func (dc *BasicDeploymentController) handleNew(ctx kapi.Context, deployment *deployapi.Deployment) deployapi.DeploymentStatus {
controllers := &kapi.ReplicationControllerList{}
var err error
configID, hasConfigID := deployment.Labels[deployapi.DeploymentConfigLabel]
if hasConfigID {
selector, _ := labels.ParseSelector(deployapi.DeploymentConfigLabel + "=" + configID)
controllers, err = dc.ReplicationControllerClient.ListReplicationControllers(ctx, selector)
if err != nil {
glog.V(2).Infof("Unable to get list of replication controllers for previous deploymentConfig %s: %v\n", configID, err)
return deployapi.DeploymentStatusFailed
}
}
controller := &kapi.ReplicationController{
DesiredState: deployment.ControllerTemplate,
Labels: map[string]string{deployapi.DeploymentConfigLabel: configID, "deployment": deployment.ID},
}
if controller.DesiredState.PodTemplate.Labels == nil {
controller.DesiredState.PodTemplate.Labels = make(map[string]string)
}
controller.DesiredState.PodTemplate.Labels[deployapi.DeploymentConfigLabel] = configID
controller.DesiredState.PodTemplate.Labels["deployment"] = deployment.ID
glog.V(2).Infof("Creating replicationController for deployment %s", deployment.ID)
if _, err := dc.ReplicationControllerClient.CreateReplicationController(ctx, controller); err != nil {
glog.V(2).Infof("An error occurred creating the replication controller for deployment %s: %v", deployment.ID, err)
return deployapi.DeploymentStatusFailed
}
allProcessed := true
// For this simple deploy, remove previous replication controllers
for _, rc := range controllers.Items {
configID, _ := deployment.Labels[deployapi.DeploymentConfigLabel]
glog.V(2).Infof("Stopping replication controller for previous deploymentConfig %s: %v", configID, rc.ID)
controller, err := dc.ReplicationControllerClient.GetReplicationController(ctx, rc.ID)
if err != nil {
glog.V(2).Infof("Unable to get replication controller %s for previous deploymentConfig %s: %#v\n", rc.ID, configID, err)
allProcessed = false
continue
}
controller.DesiredState.Replicas = 0
glog.V(2).Infof("Settings Replicas=0 for replicationController %s for previous deploymentConfig %s", rc.ID, configID)
if _, err := dc.ReplicationControllerClient.UpdateReplicationController(ctx, controller); err != nil {
glog.V(2).Infof("Unable to stop replication controller %s for previous deploymentConfig %s: %#v\n", rc.ID, configID, err)
allProcessed = false
continue
}
}
for _, rc := range controllers.Items {
configID, _ := deployment.Labels[deployapi.DeploymentConfigLabel]
glog.V(2).Infof("Deleting replication controller %s for previous deploymentConfig %s", rc.ID, configID)
err := dc.ReplicationControllerClient.DeleteReplicationController(ctx, rc.ID)
if err != nil {
glog.V(2).Infof("Unable to remove replication controller %s for previous deploymentConfig %s:%#v\n", rc.ID, configID, err)
allProcessed = false
continue
}
}
if allProcessed {
return deployapi.DeploymentStatusComplete
}
return deployapi.DeploymentStatusFailed
}