@@ -18,6 +18,7 @@ import (
18
18
"cmp"
19
19
"context"
20
20
"errors"
21
+ "time"
21
22
22
23
kubeconfig "github.com/pipe-cd/pipecd/pkg/app/pipedv1/plugin/kubernetes/config"
23
24
"github.com/pipe-cd/pipecd/pkg/app/pipedv1/plugin/kubernetes/provider"
@@ -178,6 +179,55 @@ func (p *Plugin) executeK8sSyncStage(ctx context.Context, input *sdk.ExecuteStag
178
179
return sdk .StageStatusSuccess
179
180
}
180
181
182
+ // Wait for all applied manifests to be stable.
183
+ // In theory, we don't need to wait for them to be stable before going to the next step
184
+ // but waiting for a while reduces the number of Kubernetes changes in a short time.
185
+ lp .Info ("Waiting for the applied manifests to be stable" )
186
+ select {
187
+ case <- time .After (15 * time .Second ):
188
+ break
189
+ case <- ctx .Done ():
190
+ break
191
+ }
192
+
193
+ lp .Info ("Start finding all running resources but no longer defined in Git" )
194
+
195
+ namespacedLiveResources , clusterScopedLiveResources , err := provider .GetLiveResources (ctx , kubectl , deployTargetConfig .KubeConfigPath , input .Request .Deployment .ApplicationID )
196
+ if err != nil {
197
+ lp .Errorf ("Failed while getting live resources (%v)" , err )
198
+ return sdk .StageStatusFailure
199
+ }
200
+
201
+ if len (namespacedLiveResources )+ len (clusterScopedLiveResources ) == 0 {
202
+ lp .Info ("There is no data about live resource so no resource will be removed" )
203
+ return sdk .StageStatusSuccess
204
+ }
205
+
206
+ lp .Successf ("Successfully loaded %d live resources" , len (namespacedLiveResources )+ len (clusterScopedLiveResources ))
207
+
208
+ removeKeys := provider .FindRemoveResources (manifests , namespacedLiveResources , clusterScopedLiveResources )
209
+ if len (removeKeys ) == 0 {
210
+ lp .Info ("There are no live resources should be removed" )
211
+ return sdk .StageStatusSuccess
212
+ }
213
+
214
+ lp .Infof ("Start pruning %d resources" , len (removeKeys ))
215
+ var deletedCount int
216
+ for _ , key := range removeKeys {
217
+ if err := kubectl .Delete (ctx , deployTargetConfig .KubeConfigPath , key .Namespace (), key ); err != nil {
218
+ if errors .Is (err , provider .ErrNotFound ) {
219
+ lp .Infof ("Specified resource does not exist, so skip deleting the resource: %s (%v)" , key .ReadableString (), err )
220
+ continue
221
+ }
222
+ lp .Errorf ("Failed while deleting resource %s (%v)" , key .ReadableString (), err )
223
+ continue // continue to delete other resources
224
+ }
225
+ deletedCount ++
226
+ lp .Successf ("- deleted resource: %s" , key .ReadableString ())
227
+ }
228
+
229
+ lp .Successf ("Successfully deleted %d resources" , deletedCount )
230
+
181
231
return sdk .StageStatusSuccess
182
232
}
183
233
0 commit comments