feat: Implement upload permissions in docker_container resource (#693)

This commit is contained in:
Martin 2025-04-16 09:12:51 +02:00 committed by GitHub
parent 4b2fdcc868
commit d5e501c65b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 72 additions and 28 deletions

View file

@ -820,6 +820,13 @@ func resourceDockerContainer() *schema.Resource {
Optional: true,
ForceNew: true,
},
"permissions": {
Type: schema.TypeString,
Description: "The permission mode for the file in the container. Has precedence over `executable`.",
Optional: true,
ForceNew: true,
ValidateDiagFunc: validateStringMatchesPattern(`^0[0-7]{3}$`),
},
"source": {
Type: schema.TypeString,
Description: "A filename that references a file which will be uploaded as the object content. This allows for large file uploads that do not get stored in state. Conflicts with `content` & `content_base64`",

View file

@ -12,6 +12,7 @@ import (
"log"
"math/big"
"os"
"strconv"
"strings"
"time"
@ -475,10 +476,16 @@ func resourceDockerContainerCreate(ctx context.Context, d *schema.ResourceData,
}
file := upload.(map[string]interface{})["file"].(string)
executable := upload.(map[string]interface{})["executable"].(bool)
permission := upload.(map[string]interface{})["permissions"].(string)
buf := new(bytes.Buffer)
tw := tar.NewWriter(buf)
if executable {
if permission != "" {
mode, err = strconv.ParseInt(permission, 8, 32)
if err != nil {
return diag.Errorf("Error parsing permission: %s", err)
}
} else if executable {
mode = 0o744
} else {
mode = 0o644

View file

@ -675,40 +675,42 @@ func testAccCheckSwapLimit(t *testing.T) {
}
}
func TestAccDockerContainer_upload(t *testing.T) {
func TestAccDockerContainer_uploadPermission(t *testing.T) {
var c types.ContainerJSON
ctx := context.Background()
testCheck := func(*terraform.State) error {
client := testAccProvider.Meta().(*ProviderConfig).DockerClient
testCheck := func(expected_mode string) func(*terraform.State) error {
return func(*terraform.State) error {
client := testAccProvider.Meta().(*ProviderConfig).DockerClient
srcPath := "/terraform/test.txt"
r, _, err := client.CopyFromContainer(ctx, c.ID, srcPath)
if err != nil {
return fmt.Errorf("Unable to download a file from container: %s", err)
}
tr := tar.NewReader(r)
if header, err := tr.Next(); err != nil {
return fmt.Errorf("Unable to read content of tar archive: %s", err)
} else {
mode := strconv.FormatInt(header.Mode, 8)
if !strings.HasSuffix(mode, "744") {
return fmt.Errorf("File permissions are incorrect: %s", mode)
srcPath := "/terraform/test.txt"
r, _, err := client.CopyFromContainer(ctx, c.ID, srcPath)
if err != nil {
return fmt.Errorf("Unable to download a file from container: %s", err)
}
}
fbuf := new(bytes.Buffer)
if _, err := fbuf.ReadFrom(tr); err != nil {
return err
}
content := fbuf.String()
tr := tar.NewReader(r)
if header, err := tr.Next(); err != nil {
return fmt.Errorf("Unable to read content of tar archive: %s", err)
} else {
mode := strconv.FormatInt(header.Mode, 8)
if !strings.HasSuffix(mode, expected_mode) {
return fmt.Errorf("File permissions are incorrect: %s", mode)
}
}
if content != "foo" {
return fmt.Errorf("file content is invalid")
}
fbuf := new(bytes.Buffer)
if _, err := fbuf.ReadFrom(tr); err != nil {
return err
}
content := fbuf.String()
return nil
if content != "foo" {
return fmt.Errorf("file content is invalid")
}
return nil
}
}
resource.Test(t, resource.TestCase{
@ -719,7 +721,7 @@ func TestAccDockerContainer_upload(t *testing.T) {
Config: loadTestConfiguration(t, RESOURCE, "docker_container", "testAccDockerContainerUploadConfig"),
Check: resource.ComposeTestCheckFunc(
testAccContainerRunning("docker_container.foo", &c),
testCheck,
testCheck("744"),
resource.TestCheckResourceAttr("docker_container.foo", "name", "tf-test"),
resource.TestCheckResourceAttr("docker_container.foo", "upload.#", "1"),
resource.TestCheckResourceAttr("docker_container.foo", "upload.0.content", "foo"),
@ -728,6 +730,19 @@ func TestAccDockerContainer_upload(t *testing.T) {
resource.TestCheckResourceAttr("docker_container.foo", "upload.0.file", "/terraform/test.txt"),
),
},
{
Config: loadTestConfiguration(t, RESOURCE, "docker_container", "testAccDockerContainerUploadConfigPermissions"),
Check: resource.ComposeTestCheckFunc(
testAccContainerRunning("docker_container.foo", &c),
testCheck("600"),
resource.TestCheckResourceAttr("docker_container.foo", "name", "tf-test"),
resource.TestCheckResourceAttr("docker_container.foo", "upload.#", "1"),
resource.TestCheckResourceAttr("docker_container.foo", "upload.0.content", "foo"),
resource.TestCheckResourceAttr("docker_container.foo", "upload.0.content_base64", ""),
resource.TestCheckResourceAttr("docker_container.foo", "upload.0.permissions", "0600"),
resource.TestCheckResourceAttr("docker_container.foo", "upload.0.file", "/terraform/test.txt"),
),
},
},
})
}

View file

@ -0,0 +1,15 @@
resource "docker_image" "foo" {
name = "nginx:latest"
keep_locally = true
}
resource "docker_container" "foo" {
name = "tf-test"
image = docker_image.foo.image_id
upload {
content = "foo"
file = "/terraform/test.txt"
permissions = "0600"
}
}