예제 #1
0
func (a *aggregator) attach(name string, ret libswarm.Sender) error {
	if name != "" {
		// TODO: implement this?
		return fmt.Errorf("attaching to a child is not implemented")
	}

	if _, err := ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: a.server}); err != nil {
		return err
	}

	var copies sync.WaitGroup

	for _, b := range a.backends {
		r, _, err := b.Attach("")
		if err != nil {
			return err
		}
		copies.Add(1)
		go func() {
			log.Printf("copying output from %#v\n", b)
			libswarm.Copy(ret, r)
			log.Printf("finished output from %#v\n", b)
			copies.Done()
		}()
	}

	copies.Wait()
	return nil
}
예제 #2
0
func EncodeStream(sender libswarm.Sender, reader io.Reader, tag string) {
	chunk := make([]byte, 4096)
	for {
		n, err := reader.Read(chunk)
		if n > 0 {
			sender.Send(&libswarm.Message{Verb: libswarm.Log, Args: []string{tag, string(chunk[0:n])}})
		}
		if err != nil {
			message := fmt.Sprintf("Error reading from stream: %v", err)
			sender.Send(&libswarm.Message{Verb: libswarm.Error, Args: []string{message}})
			break
		}
	}
}
예제 #3
0
func (c *container) attach(name string, ret libswarm.Sender) error {
	if _, err := ret.Send(&libswarm.Message{Verb: libswarm.Ack}); err != nil {
		return err
	}

	path := fmt.Sprintf("/containers/%s/attach?stdout=1&stderr=1&stream=1", c.id)

	stdoutR, stdoutW := io.Pipe()
	stderrR, stderrW := io.Pipe()
	go utils.EncodeStream(ret, stdoutR, "stdout")
	go utils.EncodeStream(ret, stderrR, "stderr")
	c.backend.client.hijack("POST", path, nil, stdoutW, stderrW)

	return nil
}
예제 #4
0
func (b *dockerClientBackend) attach(name string, ret libswarm.Sender) error {
	if name == "" {
		ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: b.Server})
		<-make(chan struct{})
	} else {
		path := fmt.Sprintf("/containers/%s/json", name)
		resp, err := b.client.call("GET", path, "")
		if err != nil {
			return err
		}
		respBody, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		if resp.StatusCode != 200 {
			return fmt.Errorf("%s", respBody)
		}
		c := b.newContainer(name)
		ret.Send(&libswarm.Message{Verb: libswarm.Ack, Ret: c})
	}
	return nil
}