go-dockerclient`UploadToContainer` tar示例

Unlike the python docker client which I've been using there seems to be very few examples for how to use go-dockerclient. I'm trying to work out how to upload a tar archive to a docker container using UploadToContainer which is documented here: https://godoc.org/github.com/fsouza/go-dockerclient#Client.UploadToContainer

I've built a .tar archive in memory which looks like this:

import (
    "archive/tar"
    "bytes"
    "fmt"
    "log"
)
func main() {
    // Create a buffer to write our archive to.
    buf := new(bytes.Buffer)

    // Create a new tar archive.
    tw := tar.NewWriter(buf)

    // Add some files to the archive.
    var files = []struct {
        Name, Body string
    }{
        {"file1.txt", "This archive contains some text files."},
        {"file2.txt", "Gopher names:
George
Geoffrey
Gonzo"},
        {"file3.txt", "Get animal handling license."},
    }
    for _, file := range files {
        hdr := &tar.Header{
            Name: file.Name,
            Mode: 0600,
            Size: int64(len(file.Body)),
        }
        if err := tw.WriteHeader(hdr); err != nil {
            log.Fatalln(err)
        }
        if _, err := tw.Write([]byte(file.Body)); err != nil {
            log.Fatalln(err)
        }
    }
    // Make sure to check the error on Close.
        if err := tw.Close(); err != nil {
         log.Fatalln(err)
    }
    fmt.Print(buf)

I've also successfully created a docker-client like this:

import (
    "fmt"

    "github.com/fsouza/go-dockerclient"
        "os"
)

func main() {
    endpoint := "https://localhost:52376"
    path := os.Getenv("DOCKER_CERT_PATH")
    ca := fmt.Sprintf("%s/ca.pem", path)
    cert := fmt.Sprintf("%s/cert.pem", path)
    key := fmt.Sprintf("%s/key.pem", path)
    client, _ := docker.NewTLSClient(endpoint, cert, key, ca)

I have a running container called nginx-ssl and I need to upload the tar archive to the container but can't work out whats needed to write the tar to my container.

This what I do using python where data is an in memory tar object thats been pre-created.

cli.put_archive(container='nginx-ssl', path="/keys", data=newtar)

UPDATE ++++++

I just tried this:

input := bytes.NewBufferString("test")
    uploadOpts := docker.UploadToContainerOptions{
        InputStream: input,
        Path:        "/test-test",
    }

    err := client.UploadToContainer("20e0c347cd41", uploadOpts)
    if err != nil {
        print(err)
    }

20e0c347cd41 is the "CONTAINER ID"

which returns this error:

(0xd60088,0xc820278100)

Then I tried this:

//input := bytes.NewBufferString(buf)
    uploadOpts := docker.UploadToContainerOptions{
        InputStream: buf,
        Path:        "/test-test.txt",
    }

    err := client.UploadToContainer("nginx-ssl", uploadOpts)
    if err != nil {
        print(err)
    }

where InputStream: buf is the output from my tar archive shown above. This throws the following error:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x2df8]

goroutine 1 [running]:
panic(0x3d3420, 0xc82000a0d0)

but nothing gets uploaded.

In case you still need it, that is how I have managed to upload a file (named test.txt) onto the container(in the /data dir) using go-dockerclient.

content := "File content"

buf := new(bytes.Buffer)
tw := tar.NewWriter(buf)
hdr := &tar.Header{
    Name: "test.txt",
    Mode: 0644,
    Size: int64(len(content)),
}
err := tw.WriteHeader(hdr)
if err != nil {
    fmt.Println(err.Error())
}
_, err = tw.Write([]byte(content))
if err != nil {
    fmt.Println(err.Error())
}

in := sT{bytes.NewBufferString(string(buf.Bytes()))}
opts := docker.UploadToContainerOptions{Path: "data", InputStream: in}
cont, err := client.CreateContainer(options)
if err != nil {
    log.Printf(err.Error())
    return
}
err = client.UploadToContainer(container.ID, opts)

and sT is defined as:

type sT struct {
   *bytes.Buffer
}

You might still improve the code (like use a better aproach for the buffer), but for my tests this is ok. The result is /data/test.txt containing the text "File content"

HTH