Skip to content

Commit d656fa3

Browse files
committed
restart plugin: support binary log uri
Introduce LogURIGenerator helper function in cio package. It is used in the restart options, like WithBinaryLogURI and WithFileLogURI. And restart.LogPathLabel might be used in production and work well. In order to reduce breaking change, the LogPathLabel is still recognized if new LogURILabel is not set. In next release 1.5, the LogPathLabel will be removed. Signed-off-by: Wei Fu <fuweid89@gmail.com>
1 parent 38cb1c1 commit d656fa3

File tree

5 files changed

+135
-21
lines changed

5 files changed

+135
-21
lines changed

cio/io.go

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -245,19 +245,11 @@ func LogURI(uri *url.URL) Creator {
245245
// BinaryIO forwards container STDOUT|STDERR directly to a logging binary
246246
func BinaryIO(binary string, args map[string]string) Creator {
247247
return func(_ string) (IO, error) {
248-
binary = filepath.Clean(binary)
249-
if !strings.HasPrefix(binary, "/") {
250-
return nil, errors.New("absolute path needed")
251-
}
252-
uri := &url.URL{
253-
Scheme: "binary",
254-
Path: binary,
255-
}
256-
q := uri.Query()
257-
for k, v := range args {
258-
q.Set(k, v)
248+
uri, err := LogURIGenerator("binary", binary, args)
249+
if err != nil {
250+
return nil, err
259251
}
260-
uri.RawQuery = q.Encode()
252+
261253
res := uri.String()
262254
return &logURI{
263255
config: Config{
@@ -272,14 +264,11 @@ func BinaryIO(binary string, args map[string]string) Creator {
272264
// If the log file already exists, the logs will be appended to the file.
273265
func LogFile(path string) Creator {
274266
return func(_ string) (IO, error) {
275-
path = filepath.Clean(path)
276-
if !strings.HasPrefix(path, "/") {
277-
return nil, errors.New("absolute path needed")
278-
}
279-
uri := &url.URL{
280-
Scheme: "file",
281-
Path: path,
267+
uri, err := LogURIGenerator("file", path, nil)
268+
if err != nil {
269+
return nil, err
282270
}
271+
283272
res := uri.String()
284273
return &logURI{
285274
config: Config{
@@ -290,6 +279,30 @@ func LogFile(path string) Creator {
290279
}
291280
}
292281

282+
// LogURIGenerator is the helper to generate log uri with specific scheme.
283+
func LogURIGenerator(scheme string, path string, args map[string]string) (*url.URL, error) {
284+
path = filepath.Clean(path)
285+
if !strings.HasPrefix(path, "/") {
286+
return nil, errors.New("absolute path needed")
287+
}
288+
289+
uri := &url.URL{
290+
Scheme: scheme,
291+
Path: path,
292+
}
293+
294+
if len(args) == 0 {
295+
return uri, nil
296+
}
297+
298+
q := uri.Query()
299+
for k, v := range args {
300+
q.Set(k, v)
301+
}
302+
uri.RawQuery = q.Encode()
303+
return uri, nil
304+
}
305+
293306
type logURI struct {
294307
config Config
295308
}

cio/io_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,47 @@ func TestLogFileFailOnRelativePath(t *testing.T) {
195195
_, err := LogFile("./file.txt")("!")
196196
assert.Error(t, err, "absolute path needed")
197197
}
198+
199+
func TestLogURIGenerator(t *testing.T) {
200+
for _, tc := range []struct {
201+
scheme string
202+
path string
203+
args map[string]string
204+
expected string
205+
err string
206+
}{
207+
{
208+
scheme: "fifo",
209+
path: "/full/path/pipe.fifo",
210+
expected: "fifo:///full/path/pipe.fifo",
211+
},
212+
{
213+
scheme: "file",
214+
path: "/full/path/file.txt",
215+
args: map[string]string{
216+
"maxSize": "100MB",
217+
},
218+
expected: "file:///full/path/file.txt?maxSize=100MB",
219+
},
220+
{
221+
scheme: "binary",
222+
path: "/full/path/bin",
223+
args: map[string]string{
224+
"id": "testing",
225+
},
226+
expected: "binary:///full/path/bin?id=testing",
227+
},
228+
{
229+
scheme: "unknown",
230+
path: "nowhere",
231+
err: "absolute path needed",
232+
},
233+
} {
234+
uri, err := LogURIGenerator(tc.scheme, tc.path, tc.args)
235+
if err != nil {
236+
assert.Error(t, err, tc.err)
237+
continue
238+
}
239+
assert.Equal(t, tc.expected, uri.String())
240+
}
241+
}

runtime/restart/monitor/change.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ package monitor
1818

1919
import (
2020
"context"
21+
"net/url"
2122
"syscall"
2223

2324
"github.com/containerd/containerd"
2425
"github.com/containerd/containerd/cio"
26+
"github.com/pkg/errors"
27+
"github.com/sirupsen/logrus"
2528
)
2629

2730
type stopChange struct {
@@ -34,14 +37,30 @@ func (s *stopChange) apply(ctx context.Context, client *containerd.Client) error
3437

3538
type startChange struct {
3639
container containerd.Container
37-
logPath string
40+
logURI string
41+
42+
// Deprecated(in release 1.5): but recognized now, prefer to use logURI
43+
logPath string
3844
}
3945

4046
func (s *startChange) apply(ctx context.Context, client *containerd.Client) error {
4147
log := cio.NullIO
42-
if s.logPath != "" {
48+
49+
if s.logURI != "" {
50+
uri, err := url.Parse(s.logURI)
51+
if err != nil {
52+
return errors.Wrapf(err, "failed to parse %v into url", s.logURI)
53+
}
54+
log = cio.LogURI(uri)
55+
} else if s.logPath != "" {
4356
log = cio.LogFile(s.logPath)
4457
}
58+
59+
if s.logURI != "" && s.logPath != "" {
60+
logrus.Warnf("LogPathLabel=%v has been deprecated, using LogURILabel=%v",
61+
s.logPath, s.logURI)
62+
}
63+
4564
killTask(ctx, s.container)
4665
task, err := s.container.NewTask(ctx, log)
4766
if err != nil {

runtime/restart/monitor/monitor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ func (m *monitor) monitor(ctx context.Context) ([]change, error) {
200200
changes = append(changes, &startChange{
201201
container: c,
202202
logPath: labels[restart.LogPathLabel],
203+
logURI: labels[restart.LogURILabel],
203204
})
204205
case containerd.Stopped:
205206
changes = append(changes, &stopChange{

runtime/restart/restart.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,53 @@ import (
3333
"context"
3434

3535
"github.com/containerd/containerd"
36+
"github.com/containerd/containerd/cio"
3637
"github.com/containerd/containerd/containers"
3738
)
3839

3940
const (
4041
// StatusLabel sets the restart status label for a container
4142
StatusLabel = "containerd.io/restart.status"
43+
// LogURILabel sets the restart log uri label for a container
44+
LogURILabel = "containerd.io/restart.loguri"
45+
4246
// LogPathLabel sets the restart log path label for a container
47+
//
48+
// Deprecated(in release 1.5): use LogURILabel
4349
LogPathLabel = "containerd.io/restart.logpath"
4450
)
4551

52+
// WithBinaryLogURI sets the binary-type log uri for a container.
53+
func WithBinaryLogURI(binary string, args map[string]string) func(context.Context, *containerd.Client, *containers.Container) error {
54+
return func(_ context.Context, _ *containerd.Client, c *containers.Container) error {
55+
uri, err := cio.LogURIGenerator("binary", binary, args)
56+
if err != nil {
57+
return err
58+
}
59+
60+
ensureLabels(c)
61+
c.Labels[LogURILabel] = uri.String()
62+
return nil
63+
}
64+
}
65+
66+
// WithFileLogURI sets the file-type log uri for a container.
67+
func WithFileLogURI(path string) func(context.Context, *containerd.Client, *containers.Container) error {
68+
return func(_ context.Context, _ *containerd.Client, c *containers.Container) error {
69+
uri, err := cio.LogURIGenerator("file", path, nil)
70+
if err != nil {
71+
return err
72+
}
73+
74+
ensureLabels(c)
75+
c.Labels[LogURILabel] = uri.String()
76+
return nil
77+
}
78+
}
79+
4680
// WithLogPath sets the log path for a container
81+
//
82+
// Deprecated(in release 1.5): use WithFileLogURI.
4783
func WithLogPath(path string) func(context.Context, *containerd.Client, *containers.Container) error {
4884
return func(_ context.Context, _ *containerd.Client, c *containers.Container) error {
4985
ensureLabels(c)
@@ -68,6 +104,7 @@ func WithNoRestarts(_ context.Context, _ *containerd.Client, c *containers.Conta
68104
}
69105
delete(c.Labels, StatusLabel)
70106
delete(c.Labels, LogPathLabel)
107+
delete(c.Labels, LogURILabel)
71108
return nil
72109
}
73110

0 commit comments

Comments
 (0)