Add Load for container and Task with Attach
This adds both container and task loading of running tasks as well as reattaching to the IO of the task after load. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
@@ -4,14 +4,17 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func empty() IOCreation {
|
||||
return BufferedIO(bytes.NewBuffer(nil), bytes.NewBuffer(nil), bytes.NewBuffer(nil))
|
||||
null := ioutil.Discard
|
||||
return NewIO(bytes.NewBuffer(nil), null, null)
|
||||
}
|
||||
|
||||
func TestContainerList(t *testing.T) {
|
||||
@@ -170,7 +173,7 @@ func TestContainerOutput(t *testing.T) {
|
||||
defer container.Delete(ctx)
|
||||
|
||||
stdout := bytes.NewBuffer(nil)
|
||||
task, err := container.NewTask(ctx, BufferedIO(bytes.NewBuffer(nil), stdout, bytes.NewBuffer(nil)))
|
||||
task, err := container.NewTask(ctx, NewIO(bytes.NewBuffer(nil), stdout, bytes.NewBuffer(nil)))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
@@ -445,3 +448,132 @@ func TestContainerCloseStdin(t *testing.T) {
|
||||
t.Errorf("expected output %q but received %q", expected, output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerAttach(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
client, err := New(address)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
var (
|
||||
ctx = context.Background()
|
||||
id = "ContainerAttach"
|
||||
)
|
||||
image, err := client.GetImage(ctx, testImage)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
spec, err := GenerateSpec(WithImageConfig(ctx, image), WithProcessArgs("cat"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
container, err := client.NewContainer(ctx, id, spec, WithImage(image), WithNewRootFS(id, image))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer container.Delete(ctx)
|
||||
|
||||
expected := "hello\n"
|
||||
stdout := bytes.NewBuffer(nil)
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
or, ow, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
io.Copy(stdout, or)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
// TODO: return fifo information from shim based on task/process
|
||||
dir, err := ioutil.TempDir("", "attach")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
task, err := container.NewTask(ctx, WithIO(r, ow, ioutil.Discard, dir))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer task.Delete(ctx)
|
||||
originalIO := task.IO()
|
||||
|
||||
statusC := make(chan uint32, 1)
|
||||
go func() {
|
||||
status, err := task.Wait(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
statusC <- status
|
||||
}()
|
||||
|
||||
if err := task.Start(ctx); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, expected); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
w.Close()
|
||||
|
||||
// load the container and re-load the task
|
||||
if container, err = client.LoadContainer(ctx, id); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
// create new IO for the loaded task
|
||||
if r, w, err = os.Pipe(); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if task, err = container.LoadTask(ctx, WithIO(r, ow, ioutil.Discard, dir)); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, expected); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
w.Close()
|
||||
|
||||
if err := task.CloseStdin(ctx); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
<-statusC
|
||||
|
||||
originalIO.Close()
|
||||
if _, err := task.Delete(ctx); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ow.Close()
|
||||
|
||||
wg.Wait()
|
||||
output := stdout.String()
|
||||
|
||||
// we wrote the same thing after attach
|
||||
expected = expected + expected
|
||||
if output != expected {
|
||||
t.Errorf("expected output %q but received %q", expected, output)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user