Skip to content

Commit 1baefc9

Browse files
authored
Merge pull request containerd#128 from Random-Liu/add-container-attach
Add container attach
2 parents 81f3c12 + 857f133 commit 1baefc9

25 files changed

+870
-379
lines changed

hack/test-cri.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ source $(dirname "${BASH_SOURCE[0]}")/test-utils.sh
2121
# FOCUS focuses the test to run.
2222
FOCUS=${FOCUS:-}
2323
# SKIP skips the test to skip.
24-
SKIP=${SKIP:-"attach|RunAsUser"}
24+
SKIP=${SKIP:-"RunAsUser"}
2525
REPORT_DIR=${REPORT_DIR:-"/tmp/test-cri"}
2626

2727
if [[ -z "${GOPATH}" ]]; then

pkg/ioutil/write_closer.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package ioutil
18+
19+
import "io"
20+
21+
// writeCloseInformer wraps passed in write closer with a close channel.
22+
// Caller could wait on the close channel for the write closer to be
23+
// closed.
24+
type writeCloseInformer struct {
25+
close chan struct{}
26+
wc io.WriteCloser
27+
}
28+
29+
// NewWriteCloseInformer creates the writeCloseInformer from a write closer.
30+
func NewWriteCloseInformer(wc io.WriteCloser) (io.WriteCloser, <-chan struct{}) {
31+
close := make(chan struct{})
32+
return &writeCloseInformer{
33+
close: close,
34+
wc: wc,
35+
}, close
36+
}
37+
38+
// Write passes through the data into the internal write closer.
39+
func (w *writeCloseInformer) Write(p []byte) (int, error) {
40+
return w.wc.Write(p)
41+
}
42+
43+
// Close closes the internal write closer and inform the close channel.
44+
func (w *writeCloseInformer) Close() error {
45+
err := w.wc.Close()
46+
close(w.close)
47+
return err
48+
}
49+
50+
// nopWriteCloser wraps passed in writer with a nop close function.
51+
type nopWriteCloser struct {
52+
w io.Writer
53+
}
54+
55+
// NewNopWriteCloser creates the nopWriteCloser from a writer.
56+
func NewNopWriteCloser(w io.Writer) io.WriteCloser {
57+
return &nopWriteCloser{w: w}
58+
}
59+
60+
// Write passes through the data into the internal writer.
61+
func (n *nopWriteCloser) Write(p []byte) (int, error) {
62+
return n.w.Write(p)
63+
}
64+
65+
// Close is a nop close function.
66+
func (n *nopWriteCloser) Close() error {
67+
return nil
68+
}

pkg/ioutil/write_closer_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package ioutil
18+
19+
import (
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
)
24+
25+
func TestWriteCloseInformer(t *testing.T) {
26+
original := &writeCloser{}
27+
wci, close := NewWriteCloseInformer(original)
28+
data := "test"
29+
30+
n, err := wci.Write([]byte(data))
31+
assert.Equal(t, len(data), n)
32+
assert.Equal(t, data, original.buf.String())
33+
assert.NoError(t, err)
34+
35+
select {
36+
case <-close:
37+
assert.Fail(t, "write closer closed")
38+
default:
39+
}
40+
41+
wci.Close()
42+
assert.True(t, original.closed)
43+
44+
select {
45+
case <-close:
46+
default:
47+
assert.Fail(t, "write closer not closed")
48+
}
49+
}

pkg/ioutil/writer_group.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package ioutil
18+
19+
import (
20+
"errors"
21+
"io"
22+
"sync"
23+
24+
"github.com/golang/glog"
25+
)
26+
27+
// WriterGroup is a group of writers. Writer could be dynamically
28+
// added and removed.
29+
type WriterGroup struct {
30+
mu sync.Mutex
31+
writers map[string]io.WriteCloser
32+
closed bool
33+
}
34+
35+
var _ io.Writer = &WriterGroup{}
36+
37+
// NewWriterGroup creates an empty writer group.
38+
func NewWriterGroup() *WriterGroup {
39+
return &WriterGroup{
40+
writers: make(map[string]io.WriteCloser),
41+
}
42+
}
43+
44+
// Add adds a writer into the group, returns an error when writer
45+
// group is closed.
46+
func (g *WriterGroup) Add(key string, w io.WriteCloser) error {
47+
g.mu.Lock()
48+
defer g.mu.Unlock()
49+
if g.closed {
50+
return errors.New("wait group closed")
51+
}
52+
g.writers[key] = w
53+
return nil
54+
}
55+
56+
// Remove removes a writer from the group.
57+
func (g *WriterGroup) Remove(key string) {
58+
g.mu.Lock()
59+
defer g.mu.Unlock()
60+
w, ok := g.writers[key]
61+
if !ok {
62+
return
63+
}
64+
w.Close()
65+
delete(g.writers, key)
66+
}
67+
68+
// Write writes data into each writer. If a writer returns error,
69+
// it will be closed and removed from the writer group. It returns
70+
// error if writer group is empty.
71+
func (g *WriterGroup) Write(p []byte) (int, error) {
72+
g.mu.Lock()
73+
defer g.mu.Unlock()
74+
for k, w := range g.writers {
75+
n, err := w.Write(p)
76+
if err != nil {
77+
glog.Errorf("Writer %q write error: %v", k, err)
78+
} else if len(p) != n {
79+
glog.Errorf("Writer %q short write error", k)
80+
} else {
81+
continue
82+
}
83+
// The writer is closed or in bad state, remove it.
84+
w.Close()
85+
delete(g.writers, k)
86+
}
87+
if len(g.writers) == 0 {
88+
return 0, errors.New("writer group is empty")
89+
}
90+
return len(p), nil
91+
}
92+
93+
// Close closes the writer group. Write or Add will return error
94+
// after closed.
95+
func (g *WriterGroup) Close() {
96+
g.mu.Lock()
97+
defer g.mu.Unlock()
98+
for _, w := range g.writers {
99+
w.Close()
100+
}
101+
g.writers = nil
102+
g.closed = true
103+
}

pkg/ioutil/writer_group_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package ioutil
18+
19+
import (
20+
"bytes"
21+
"testing"
22+
23+
"github.com/stretchr/testify/assert"
24+
)
25+
26+
type writeCloser struct {
27+
buf bytes.Buffer
28+
closed bool
29+
}
30+
31+
func (wc *writeCloser) Write(p []byte) (int, error) {
32+
return wc.buf.Write(p)
33+
}
34+
35+
func (wc *writeCloser) Close() error {
36+
wc.closed = true
37+
return nil
38+
}
39+
40+
func TestEmptyWriterGroup(t *testing.T) {
41+
wg := NewWriterGroup()
42+
_, err := wg.Write([]byte("test"))
43+
assert.Error(t, err)
44+
}
45+
46+
func TestClosedWriterGroup(t *testing.T) {
47+
wg := NewWriterGroup()
48+
wc := &writeCloser{}
49+
key, data := "test key", "test data"
50+
51+
err := wg.Add(key, wc)
52+
assert.NoError(t, err)
53+
54+
n, err := wg.Write([]byte(data))
55+
assert.Equal(t, len(data), n)
56+
assert.Equal(t, data, wc.buf.String())
57+
assert.NoError(t, err)
58+
59+
wg.Close()
60+
assert.True(t, wc.closed)
61+
62+
err = wg.Add(key, &writeCloser{})
63+
assert.Error(t, err)
64+
65+
_, err = wg.Write([]byte(data))
66+
assert.Error(t, err)
67+
}
68+
69+
func TestAddRemoveWriter(t *testing.T) {
70+
wg := NewWriterGroup()
71+
wc1, wc2 := &writeCloser{}, &writeCloser{}
72+
key1, key2 := "test key 1", "test key 2"
73+
74+
err := wg.Add(key1, wc1)
75+
assert.NoError(t, err)
76+
_, err = wg.Write([]byte("test data 1"))
77+
assert.NoError(t, err)
78+
assert.Equal(t, "test data 1", wc1.buf.String())
79+
80+
err = wg.Add(key2, wc2)
81+
assert.NoError(t, err)
82+
_, err = wg.Write([]byte("test data 2"))
83+
assert.NoError(t, err)
84+
assert.Equal(t, "test data 1test data 2", wc1.buf.String())
85+
assert.Equal(t, "test data 2", wc2.buf.String())
86+
87+
wg.Remove(key1)
88+
_, err = wg.Write([]byte("test data 3"))
89+
assert.NoError(t, err)
90+
assert.Equal(t, "test data 1test data 2", wc1.buf.String())
91+
assert.Equal(t, "test data 2test data 3", wc2.buf.String())
92+
93+
wg.Close()
94+
}

pkg/server/agents/agents.go

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)