Skip to content

Commit ddb5e16

Browse files
committed
Enhance logging driver and ctr tasks to support windows
Signed-off-by: Maksim An <[email protected]>
1 parent 83f8d61 commit ddb5e16

4 files changed

Lines changed: 170 additions & 43 deletions

File tree

cmd/ctr/commands/tasks/tasks_windows.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package tasks
1818

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

2324
"github.com/containerd/console"
@@ -67,6 +68,12 @@ func NewTask(ctx gocontext.Context, client *containerd.Client, container contain
6768
ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStreams(con, con, nil), cio.WithTerminal}, ioOpts...)...)
6869
} else if nullIO {
6970
ioCreator = cio.NullIO
71+
} else if logURI != "" {
72+
u, err := url.Parse(logURI)
73+
if err != nil {
74+
return nil, err
75+
}
76+
ioCreator = cio.LogURI(u)
7077
} else {
7178
ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...)
7279
}

runtime/v2/logging/logging.go

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// +build !windows
2-
31
/*
42
Copyright The containerd Authors.
53
@@ -20,12 +18,7 @@ package logging
2018

2119
import (
2220
"context"
23-
"fmt"
2421
"io"
25-
"os"
26-
"os/signal"
27-
28-
"golang.org/x/sys/unix"
2922
)
3023

3124
// Config of the container logs
@@ -38,39 +31,3 @@ type Config struct {
3831

3932
// LoggerFunc is implemented by custom v2 logging binaries
4033
type LoggerFunc func(context.Context, *Config, func() error) error
41-
42-
// Run the logging driver
43-
func Run(fn LoggerFunc) {
44-
ctx, cancel := context.WithCancel(context.Background())
45-
defer cancel()
46-
47-
config := &Config{
48-
ID: os.Getenv("CONTAINER_ID"),
49-
Namespace: os.Getenv("CONTAINER_NAMESPACE"),
50-
Stdout: os.NewFile(3, "CONTAINER_STDOUT"),
51-
Stderr: os.NewFile(4, "CONTAINER_STDERR"),
52-
}
53-
var (
54-
s = make(chan os.Signal, 32)
55-
errCh = make(chan error, 1)
56-
wait = os.NewFile(5, "CONTAINER_WAIT")
57-
)
58-
signal.Notify(s, unix.SIGTERM)
59-
60-
go func() {
61-
errCh <- fn(ctx, config, wait.Close)
62-
}()
63-
64-
for {
65-
select {
66-
case <-s:
67-
cancel()
68-
case err := <-errCh:
69-
if err != nil {
70-
fmt.Fprintln(os.Stderr, err)
71-
os.Exit(1)
72-
}
73-
os.Exit(0)
74-
}
75-
}
76-
}

runtime/v2/logging/logging_unix.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// +build !windows
2+
3+
/*
4+
Copyright The containerd Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package logging
20+
21+
import (
22+
"context"
23+
"fmt"
24+
"os"
25+
"os/signal"
26+
27+
"golang.org/x/sys/unix"
28+
)
29+
30+
// Run the logging driver
31+
func Run(fn LoggerFunc) {
32+
ctx, cancel := context.WithCancel(context.Background())
33+
defer cancel()
34+
35+
config := &Config{
36+
ID: os.Getenv("CONTAINER_ID"),
37+
Namespace: os.Getenv("CONTAINER_NAMESPACE"),
38+
Stdout: os.NewFile(3, "CONTAINER_STDOUT"),
39+
Stderr: os.NewFile(4, "CONTAINER_STDERR"),
40+
}
41+
var (
42+
sigCh = make(chan os.Signal, 32)
43+
errCh = make(chan error, 1)
44+
wait = os.NewFile(5, "CONTAINER_WAIT")
45+
)
46+
signal.Notify(sigCh, unix.SIGTERM)
47+
48+
go func() {
49+
errCh <- fn(ctx, config, wait.Close)
50+
}()
51+
52+
for {
53+
select {
54+
case <-sigCh:
55+
cancel()
56+
case err := <-errCh:
57+
if err != nil {
58+
fmt.Fprintln(os.Stderr, err)
59+
os.Exit(1)
60+
}
61+
os.Exit(0)
62+
}
63+
}
64+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// +build windows
2+
3+
/*
4+
Copyright The containerd Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package logging
20+
21+
import (
22+
"context"
23+
"fmt"
24+
"net"
25+
"os"
26+
"os/signal"
27+
"syscall"
28+
29+
"github.com/Microsoft/go-winio"
30+
"github.com/pkg/errors"
31+
)
32+
33+
// Run the logging driver
34+
func Run(fn LoggerFunc) {
35+
err := runInternal(fn)
36+
if err != nil {
37+
fmt.Fprintln(os.Stderr, err)
38+
os.Exit(1)
39+
}
40+
os.Exit(0)
41+
}
42+
43+
func runInternal(fn LoggerFunc) error {
44+
ctx, cancel := context.WithCancel(context.Background())
45+
defer cancel()
46+
47+
var (
48+
soutPipe, serrPipe, waitPipe string
49+
sout, serr, wait net.Conn
50+
ok bool
51+
err error
52+
)
53+
54+
if soutPipe, ok = os.LookupEnv("CONTAINER_STDOUT"); !ok {
55+
return errors.New("'CONTAINER_STDOUT' environment variable missing")
56+
}
57+
if sout, err = winio.DialPipeContext(ctx, soutPipe); err != nil {
58+
return errors.Wrap(err, "unable to dial stdout pipe")
59+
}
60+
61+
if serrPipe, ok = os.LookupEnv("CONTAINER_STDERR"); !ok {
62+
return errors.New("'CONTAINER_STDERR' environment variable missing")
63+
}
64+
if serr, err = winio.DialPipeContext(ctx, serrPipe); err != nil {
65+
return errors.Wrap(err, "unable to dial stderr pipe")
66+
}
67+
68+
waitPipe = os.Getenv("CONTAINER_WAIT")
69+
if wait, err = winio.DialPipeContext(ctx, waitPipe); err != nil {
70+
return errors.Wrap(err, "unable to dial wait pipe")
71+
}
72+
73+
config := &Config{
74+
ID: os.Getenv("CONTAINER_ID"),
75+
Namespace: os.Getenv("CONTAINER_NAMESPACE"),
76+
Stdout: sout,
77+
Stderr: serr,
78+
}
79+
80+
var (
81+
sigCh = make(chan os.Signal, 2)
82+
errCh = make(chan error, 1)
83+
)
84+
85+
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
86+
87+
go func() {
88+
errCh <- fn(ctx, config, wait.Close)
89+
}()
90+
91+
for {
92+
select {
93+
case <-sigCh:
94+
cancel()
95+
case err = <-errCh:
96+
return err
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)