3

我正在尝试使用 Go docker API 获取挂载的文件内容:

文件secret.txt存储一行TOKEN=MY_TOKEN

代码:

cli, err := client.NewEnvClient()
if err != nil {
    panic(err)
}
defer cli.Close()

ctx := context.Background()

_, err = cli.ImagePull(ctx, "alpine", types.ImagePullOptions{})
if err != nil {
    panic(err)

}

containerConfig := &container.Config{
    Image: "alpine",
    Cmd:   []string{"echo", "hello world"},
}

// mounted file
h := container.HostConfig{
    Binds: []string{"/etc/secret.txt"},
}

resp, err := cli.ContainerCreate(ctx, containerConfig, &h, nil, "")
if err != nil {
    panic(err)
}

rc, _, err := cli.CopyFromContainer(context.Background(), resp.ID, "/etc/secret.txt")
if err != nil {
    fmt.Println(err.Error())
}
b, err := ioutil.ReadAll(rc)
if err != nil {
    fmt.Println(err.Error())
}
rc.Close()
fmt.Println(string(b), "  len=", len(string(b)))

我正在获取secret.txt包含其他信息的文件:

secret.txt/0040755000000000000000000000000013204637420011354 5ustar0000000000000000 len= 153

如何从文本文件中获取实际数据?谢谢

4

1 回答 1

2

首先,Binds参数是 format "source:target[:ro]",所以你应该有它"/etc/secret.txt:/etc/secret.txt",或者"/etc/secret.txt:/etc/secret.txt:ro"如果你希望它是只读的。

其次,阅读器返回的数据格式CopyFromContainer()是 tar 存档。这是对修复绑定的代码的一个小修改,并使用标准库中的 tar 从 /etc/secret 中提取字节。

func main() {
        cli, err := client.NewEnvClient()
        if err != nil {
                panic(err)
        }
        defer cli.Close()

        ctx := context.Background()

        _, err = cli.ImagePull(ctx, "alpine", types.ImagePullOptions{})
        if err != nil {
                panic(err)

        }

        containerConfig := &container.Config{
                Image: "alpine",
                Cmd:   []string{"sleep", "1h"},
        }

        // mounted file
        h := container.HostConfig{
                Binds: []string{"/etc/secret.txt:/etc/secret.txt"},
        }

        resp, err := cli.ContainerCreate(ctx, containerConfig, &h, nil, "")
        if err != nil {
                panic(err)
        }

        rc, _, err := cli.CopyFromContainer(context.Background(), resp.ID, "/etc/secret.txt")
        if err != nil {
                fmt.Println(err.Error())
        }

        tr := tar.NewReader(rc)
        var b []byte
        for {
                hdr, err := tr.Next()
                if err == io.EOF {
                        break
                }
                if err != nil {
                        break
                }
                if hdr.Name == "secret.txt" {
                        b, err = ioutil.ReadAll(tr)
                        break
                }
                fmt.Println("Name:", hdr.Name)
                if err != nil {
                        break
                }
        }
        if err != nil {
                fmt.Println(err.Error())
        }
        rc.Close()
        fmt.Printf("%q (len=%d)\n", b, len(string(b)))
}
于 2017-11-21T16:57:43.940 回答