Skip to content

Commit 4de8dd1

Browse files
Merge pull request #759 from dinhxuanvu/deployment-update
fix(deployment): Clean up orphaned deployments
2 parents c831132 + a52214c commit 4de8dd1

File tree

8 files changed

+538
-36
lines changed

8 files changed

+538
-36
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ container-codegen:
144144
docker rm temp-codegen
145145

146146
container-mockgen:
147-
docker build -t olm:mockgen -f mockgen.Dockerfile .
147+
docker build -t olm:mockgen -f mockgen.Dockerfile . --no-cache
148148
docker run --name temp-mockgen olm:mockgen /bin/true
149149
docker cp temp-mockgen:/operator-lifecycle-manager/pkg/api/wrappers/wrappersfakes/. ./pkg/api/wrappers/wrappersfakes
150150
docker cp temp-mockgen:/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes/. ./pkg/lib/operatorlister/operatorlisterfakes
@@ -176,7 +176,7 @@ release:
176176
rm -rf manifests
177177
mkdir manifests
178178
cp -R deploy/ocp/manifests/$(ver)/. manifests
179-
find ./manifests -type f -exec sed -i "/^#/d" {} \;
179+
find ./manifests -type f -exec sed -i "/^#/d" {} \;
180180
find ./manifests -type f -exec sed -i "1{/---/d}" {} \;
181181

182182
package: olmref=$(shell docker inspect --format='{{index .RepoDigests 0}}' quay.io/operator-framework/olm:$(ver))

pkg/api/wrappers/deployment_install_client.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
rbacv1 "k8s.io/api/rbac/v1"
99
apierrors "k8s.io/apimachinery/pkg/api/errors"
1010
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"k8s.io/apimachinery/pkg/labels"
1112

1213
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
1314
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
@@ -25,6 +26,7 @@ type InstallStrategyDeploymentInterface interface {
2526
DeleteDeployment(name string) error
2627
GetServiceAccountByName(serviceAccountName string) (*corev1.ServiceAccount, error)
2728
FindAnyDeploymentsMatchingNames(depNames []string) ([]*appsv1.Deployment, error)
29+
FindAnyDeploymentsMatchingLabels(label labels.Selector) ([]*appsv1.Deployment, error)
2830
}
2931

3032
type InstallStrategyDeploymentClientForNamespace struct {
@@ -118,3 +120,13 @@ func (c *InstallStrategyDeploymentClientForNamespace) FindAnyDeploymentsMatching
118120
}
119121
return deployments, nil
120122
}
123+
124+
func (c *InstallStrategyDeploymentClientForNamespace) FindAnyDeploymentsMatchingLabels(label labels.Selector) ([]*appsv1.Deployment, error) {
125+
deployments, err := c.opLister.AppsV1().DeploymentLister().Deployments(c.Namespace).List(label)
126+
// Any errors other than !exists are propagated up
127+
if err != nil && !apierrors.IsNotFound(err) {
128+
return nil, err
129+
}
130+
131+
return deployments, nil
132+
}

pkg/api/wrappers/wrappersfakes/fake_install_strategy_deployment_interface.go

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/controller/install/deployment.go

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
appsv1 "k8s.io/api/apps/v1"
88
rbac "k8s.io/api/rbac/v1"
99

10+
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
1011
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers"
1112
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
1213
)
@@ -113,14 +114,8 @@ func (i *StrategyDeploymentInstaller) Install(s Strategy) error {
113114
return err
114115
}
115116

116-
if i.previousStrategy != nil {
117-
previous, ok := i.previousStrategy.(*StrategyDetailsDeployment)
118-
if !ok {
119-
return fmt.Errorf("couldn't parse old install %s strategy with deployment installer", previous.GetStrategyName())
120-
}
121-
return i.cleanupPrevious(strategy, previous)
122-
}
123-
return nil
117+
// Clean up orphaned deployments
118+
return i.cleanupOrphanedDeployments(strategy.DeploymentSpecs)
124119
}
125120

126121
// CheckInstalled can return nil (installed), or errors
@@ -144,9 +139,15 @@ func (i *StrategyDeploymentInstaller) checkForDeployments(deploymentSpecs []Stra
144139
depNames = append(depNames, dep.Name)
145140
}
146141

147-
existingDeployments, err := i.strategyClient.FindAnyDeploymentsMatchingNames(depNames)
142+
// Check the owner is a CSV
143+
csv, ok := i.owner.(*v1alpha1.ClusterServiceVersion)
144+
if !ok {
145+
return StrategyError{Reason: StrategyErrReasonComponentMissing, Message: fmt.Sprintf("owner %s is not a CSV", i.owner.GetName())}
146+
}
147+
148+
existingDeployments, err := i.strategyClient.FindAnyDeploymentsMatchingLabels(ownerutil.CSVOwnerSelector(csv))
148149
if err != nil {
149-
return StrategyError{Reason: StrategyErrReasonComponentMissing, Message: fmt.Sprintf("error querying for %s: %s", depNames, err)}
150+
return StrategyError{Reason: StrategyErrReasonComponentMissing, Message: fmt.Sprintf("error querying existing deployments for CSV %s: %s", csv.GetName(), err)}
150151
}
151152

152153
// compare deployments to see if any need to be created/updated
@@ -181,3 +182,39 @@ func (i *StrategyDeploymentInstaller) checkForDeployments(deploymentSpecs []Stra
181182
}
182183
return nil
183184
}
185+
186+
// Clean up orphaned deployments after reinstalling deployments process
187+
func (i *StrategyDeploymentInstaller) cleanupOrphanedDeployments(deploymentSpecs []StrategyDeploymentSpec) error {
188+
// Map of deployments
189+
depNames := map[string]string{}
190+
for _, dep := range deploymentSpecs {
191+
depNames[dep.Name] = dep.Name
192+
}
193+
194+
// Check the owner is a CSV
195+
csv, ok := i.owner.(*v1alpha1.ClusterServiceVersion)
196+
if !ok {
197+
return fmt.Errorf("owner %s is not a CSV", i.owner.GetName())
198+
}
199+
200+
// Get existing deployments in CSV's namespace and owned by CSV
201+
existingDeployments, err := i.strategyClient.FindAnyDeploymentsMatchingLabels(ownerutil.CSVOwnerSelector(csv))
202+
if err != nil {
203+
return err
204+
}
205+
206+
// compare existing deployments to deployments in CSV's spec to see if any need to be deleted
207+
for _, d := range existingDeployments {
208+
if _, exists := depNames[d.GetName()]; !exists {
209+
if ownerutil.IsOwnedBy(d, i.owner) {
210+
log.Infof("found an orphaned deployment %s in namespace %s", d.GetName(), i.owner.GetNamespace())
211+
if err := i.strategyClient.DeleteDeployment(d.GetName()); err != nil {
212+
log.Warnf("error cleaning up deployment %s", d.GetName())
213+
return err
214+
}
215+
}
216+
}
217+
}
218+
219+
return nil
220+
}

0 commit comments

Comments
 (0)