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