@@ -2,10 +2,13 @@ package cloud
22
33import (
44 "context"
5+ "strings"
6+ "time"
57
68 "github.com/grafana/grafana-com-public-clients/go/gcom"
79 "github.com/grafana/terraform-provider-grafana/v4/internal/common"
810 "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
11+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
912 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1013)
1114
@@ -94,9 +97,22 @@ func resourcePluginInstallationCreate(ctx context.Context, d *schema.ResourceDat
9497 Plugin : pluginSlug ,
9598 Version : common .Ref (d .Get ("version" ).(string )),
9699 }
97- _ , _ , err := client .InstancesAPI .PostInstancePlugins (ctx , stackSlug ).
98- PostInstancePluginsRequest (req ).
99- XRequestId (ClientRequestID ()).Execute ()
100+
101+ err := retry .RetryContext (ctx , 2 * time .Minute , func () * retry.RetryError {
102+ _ , _ , err := client .InstancesAPI .PostInstancePlugins (ctx , stackSlug ).
103+ PostInstancePluginsRequest (req ).
104+ XRequestId (ClientRequestID ()).Execute ()
105+ if err != nil && strings .Contains (strings .ToLower (err .Error ()), "conflict" ) {
106+ // If the API returns a conflict error (409), it means that the plugin installation
107+ // is in progress or there's a temporary conflict. Retry after a delay.
108+ time .Sleep (10 * time .Second ) // Do not retry too fast, default is 500ms
109+ return retry .RetryableError (err )
110+ }
111+ if err != nil {
112+ return retry .NonRetryableError (err )
113+ }
114+ return nil
115+ })
100116 if err != nil {
101117 return apiError (err )
102118 }
@@ -133,6 +149,22 @@ func resourcePluginInstallationDelete(ctx context.Context, d *schema.ResourceDat
133149 }
134150 stackSlug , pluginSlug := split [0 ], split [1 ]
135151
136- _ , _ , err = client .InstancesAPI .DeleteInstancePlugin (ctx , stackSlug .(string ), pluginSlug .(string )).XRequestId (ClientRequestID ()).Execute ()
137- return apiError (err )
152+ err = retry .RetryContext (ctx , 2 * time .Minute , func () * retry.RetryError {
153+ _ , _ , err := client .InstancesAPI .DeleteInstancePlugin (ctx , stackSlug .(string ), pluginSlug .(string )).XRequestId (ClientRequestID ()).Execute ()
154+ if err != nil && strings .Contains (strings .ToLower (err .Error ()), "conflict" ) {
155+ // If the API returns a conflict error (409), it means that the plugin deletion
156+ // is in progress or there's a temporary conflict. Retry after a delay.
157+ time .Sleep (10 * time .Second ) // Do not retry too fast, default is 500ms
158+ return retry .RetryableError (err )
159+ }
160+ if err != nil {
161+ return retry .NonRetryableError (err )
162+ }
163+ return nil
164+ })
165+ if err != nil {
166+ return apiError (err )
167+ }
168+
169+ return nil
138170}
0 commit comments