fix: docker_service label can be updated without recreate (#814)

This commit is contained in:
Martin 2025-10-30 23:22:09 +01:00 committed by GitHub
parent 0607ad7eec
commit 5c27d970fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 90 additions and 15 deletions

View file

@ -56,23 +56,28 @@ func mapToLabelSet(labels map[string]string) *schema.Set {
return schema.NewSet(hashLabel, mapped)
}
var labelSchema = &schema.Resource{
Schema: map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Description: "Name of the label",
Required: true,
ForceNew: true,
func newLabelSchema(forceNew bool) *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Description: "Name of the label",
Required: true,
ForceNew: forceNew,
},
"value": {
Type: schema.TypeString,
Description: "Value of the label",
Required: true,
ForceNew: forceNew,
},
},
"value": {
Type: schema.TypeString,
Description: "Value of the label",
Required: true,
ForceNew: true,
},
},
}
}
var labelSchema = newLabelSchema(true)
var labelSchemaUpdatable = newLabelSchema(false)
// gatherImmediateSubkeys given an incomplete attribute identifier, find all
// the strings (if any) that appear after this one in the various dot-separated
// identifiers.

View file

@ -62,7 +62,7 @@ func resourceDockerService() *schema.Resource {
Description: "User-defined key/value metadata",
Optional: true,
Computed: true,
Elem: labelSchema,
Elem: labelSchemaUpdatable,
},
"task_spec": {
Type: schema.TypeList,

View file

@ -317,6 +317,54 @@ func TestAccDockerService_minimalSpec(t *testing.T) {
})
}
func TestAccDockerService_updateLabels(t *testing.T) {
ctx := context.Background()
var serviceID string
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(loadTestConfiguration(t, RESOURCE, "docker_service", "testAccDockerServiceUpdateLabels"), "prod"),
Check: resource.ComposeTestCheckFunc(
func(state *terraform.State) error {
rs, ok := state.RootModule().Resources["docker_service.foo"]
if !ok {
return fmt.Errorf("service resource not found in state")
}
if rs.Primary.ID == "" {
return fmt.Errorf("service id not set")
}
serviceID = rs.Primary.ID
return nil
},
testCheckLabelMap("docker_service.foo", "labels", map[string]string{"env": "prod"}),
),
},
{
Config: fmt.Sprintf(loadTestConfiguration(t, RESOURCE, "docker_service", "testAccDockerServiceUpdateLabels"), "staging"),
Check: resource.ComposeTestCheckFunc(
func(state *terraform.State) error {
rs, ok := state.RootModule().Resources["docker_service.foo"]
if !ok {
return fmt.Errorf("service resource not found in state")
}
if rs.Primary.ID != serviceID {
return fmt.Errorf("expected service to be updated in place, but ID changed from %s to %s", serviceID, rs.Primary.ID)
}
return nil
},
testCheckLabelMap("docker_service.foo", "labels", map[string]string{"env": "staging"}),
),
},
},
CheckDestroy: func(state *terraform.State) error {
return checkAndRemoveImages(ctx, state)
},
})
}
func TestAccDockerService_fullSpec(t *testing.T) {
var s swarm.Service

View file

@ -0,0 +1,22 @@
provider "docker" {
registry_auth {
address = "127.0.0.1:15000"
}
}
resource "docker_service" "foo" {
name = "tftest-service-labels"
labels {
label = "env"
value = "%s"
}
task_spec {
container_spec {
image = "127.0.0.1:15000/tftest-service:v1@sha256:2ca4c7a50df3515ea96106caab374759879830f6e4d6b400cee064e2e8db08c0"
stop_grace_period = "10s"
}
}
}