Skip to content

Commit 72d889d

Browse files
fix: prevent deadlock (#712)
* fix: prevent deadlock Fixes #710. While migrating from an older version using sdkv2 to terraform-plugin-framework may need to recalculate the computed attributes, it should definitely not deadlock in the meantime. Added a test where we create a repository using `7.8.0`, and then update it using the current version of this provider. Whereas before this deadlocked, it now updates as intended, and once this initial migration update has been done there is no state diff afterwards. Signed-off-by: Blake Pettersson <[email protected]> * chore: please linter Signed-off-by: Blake Pettersson <[email protected]> --------- Signed-off-by: Blake Pettersson <[email protected]>
1 parent b3fddcf commit 72d889d

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

internal/provider/resource_repository.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,18 @@ func (r *repositoryResource) Update(ctx context.Context, req resource.UpdateRequ
194194
return
195195
}
196196

197-
// Update repository
198-
sync.RepositoryMutex.Lock()
199-
defer sync.RepositoryMutex.Unlock()
197+
var updatedRepo *v1alpha1.Repository
200198

201-
updatedRepo, err := r.si.RepositoryClient.UpdateRepository(
202-
ctx,
203-
&repository.RepoUpdateRequest{Repo: repo},
204-
)
199+
func() {
200+
// Keep mutex enclosed in a function to keep the lock scoped to it and to prevent deadlocking
201+
sync.RepositoryMutex.Lock()
202+
defer sync.RepositoryMutex.Unlock()
203+
204+
updatedRepo, err = r.si.RepositoryClient.UpdateRepository(
205+
ctx,
206+
&repository.RepoUpdateRequest{Repo: repo},
207+
)
208+
}()
205209

206210
if err != nil {
207211
resp.Diagnostics.Append(diagnostics.ArgoCDAPIError("update", "repository", repo.Repo, err)...)
@@ -225,7 +229,7 @@ func (r *repositoryResource) Update(ctx context.Context, req resource.UpdateRequ
225229
tflog.Trace(ctx, fmt.Sprintf("updated repository %s", updatedRepo.Repo))
226230

227231
// Save updated data into Terraform state
228-
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
232+
resp.Diagnostics.Append(resp.State.Set(ctx, data.updateFromAPI(updatedRepo))...)
229233

230234
// Perform a read to get the latest state
231235
if !resp.Diagnostics.HasError() {

internal/provider/resource_repository_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
88
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
910
"github.com/stretchr/testify/assert"
1011
)
1112

@@ -481,6 +482,43 @@ resource "argocd_repository" "boolean_fields" {
481482
})
482483
}
483484

485+
func TestAccArgoCDRepository_ProviderUpgradeStateMigration(t *testing.T) {
486+
config := `
487+
resource "argocd_repository" "private" {
488+
count = 1
489+
repo = "https://github.com/kubernetes-sigs/kustomize"
490+
name = "gitlab-private"
491+
type = "git"
492+
}
493+
`
494+
resource.Test(t, resource.TestCase{
495+
Steps: []resource.TestStep{
496+
{
497+
ExternalProviders: map[string]resource.ExternalProvider{
498+
"argocd": {
499+
VersionConstraint: "7.8.0",
500+
Source: "argoproj-labs/argocd",
501+
},
502+
},
503+
Config: config,
504+
},
505+
{
506+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
507+
Config: config,
508+
},
509+
{
510+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
511+
Config: config,
512+
ConfigPlanChecks: resource.ConfigPlanChecks{
513+
PreApply: []plancheck.PlanCheck{
514+
plancheck.ExpectEmptyPlan(),
515+
},
516+
},
517+
},
518+
},
519+
})
520+
}
521+
484522
// TestAccArgoCDRepository_EmptyStringFieldsConsistency tests handling of empty string fields
485523
func TestAccArgoCDRepository_EmptyStringFieldsConsistency(t *testing.T) {
486524
config := `

0 commit comments

Comments
 (0)