@@ -21,17 +21,22 @@ package shim
2121import (
2222 "context"
2323 "io"
24+ "net/url"
25+ "os"
2426 "sync"
2527 "syscall"
2628
2729 "github.com/containerd/console"
30+ "github.com/containerd/containerd/namespaces"
31+ "github.com/containerd/containerd/runtime"
2832 "github.com/containerd/fifo"
33+ "github.com/pkg/errors"
2934)
3035
3136type unixPlatform struct {
3237}
3338
34- func (p * unixPlatform ) CopyConsole (ctx context.Context , console console.Console , stdin , stdout , stderr string , wg * sync.WaitGroup ) (console.Console , error ) {
39+ func (p * unixPlatform ) CopyConsole (ctx context.Context , console console.Console , id , stdin , stdout , stderr string , wg * sync.WaitGroup ) (cons console.Console , retErr error ) {
3540 var cwg sync.WaitGroup
3641 if stdin != "" {
3742 in , err := fifo .OpenFifo (ctx , stdin , syscall .O_RDONLY , 0 )
@@ -47,28 +52,98 @@ func (p *unixPlatform) CopyConsole(ctx context.Context, console console.Console,
4752 io .CopyBuffer (console , in , * p )
4853 }()
4954 }
50- outw , err := fifo . OpenFifo ( ctx , stdout , syscall . O_WRONLY , 0 )
55+ uri , err := url . Parse ( stdout )
5156 if err != nil {
52- return nil , err
57+ return nil , errors . Wrap ( err , "unable to parse stdout uri" )
5358 }
54- outr , err := fifo .OpenFifo (ctx , stdout , syscall .O_RDONLY , 0 )
55- if err != nil {
56- return nil , err
59+
60+ switch uri .Scheme {
61+ case "binary" :
62+ ns , err := namespaces .NamespaceRequired (ctx )
63+ if err != nil {
64+ return nil , err
65+ }
66+
67+ cmd := runtime .NewBinaryCmd (uri , id , ns )
68+
69+ // In case of unexpected errors during logging binary start, close open pipes
70+ var filesToClose []* os.File
71+
72+ defer func () {
73+ if retErr != nil {
74+ runtime .CloseFiles (filesToClose ... )
75+ }
76+ }()
77+
78+ // Create pipe to be used by logging binary for Stdout
79+ outR , outW , err := os .Pipe ()
80+ if err != nil {
81+ return nil , errors .Wrap (err , "failed to create stdout pipes" )
82+ }
83+ filesToClose = append (filesToClose , outR )
84+
85+ // Stderr is created for logging binary but unused when terminal is true
86+ serrR , _ , err := os .Pipe ()
87+ if err != nil {
88+ return nil , errors .Wrap (err , "failed to create stderr pipes" )
89+ }
90+ filesToClose = append (filesToClose , serrR )
91+
92+ r , w , err := os .Pipe ()
93+ if err != nil {
94+ return nil , err
95+ }
96+ filesToClose = append (filesToClose , r )
97+
98+ cmd .ExtraFiles = append (cmd .ExtraFiles , outR , serrR , w )
99+
100+ wg .Add (1 )
101+ cwg .Add (1 )
102+ go func () {
103+ cwg .Done ()
104+ io .Copy (outW , console )
105+ outW .Close ()
106+ wg .Done ()
107+ }()
108+
109+ if err := cmd .Start (); err != nil {
110+ return nil , errors .Wrap (err , "failed to start logging binary process" )
111+ }
112+
113+ // Close our side of the pipe after start
114+ if err := w .Close (); err != nil {
115+ return nil , errors .Wrap (err , "failed to close write pipe after start" )
116+ }
117+
118+ // Wait for the logging binary to be ready
119+ b := make ([]byte , 1 )
120+ if _ , err := r .Read (b ); err != nil && err != io .EOF {
121+ return nil , errors .Wrap (err , "failed to read from logging binary" )
122+ }
123+ cwg .Wait ()
124+
125+ default :
126+ outw , err := fifo .OpenFifo (ctx , stdout , syscall .O_WRONLY , 0 )
127+ if err != nil {
128+ return nil , err
129+ }
130+ outr , err := fifo .OpenFifo (ctx , stdout , syscall .O_RDONLY , 0 )
131+ if err != nil {
132+ return nil , err
133+ }
134+ wg .Add (1 )
135+ cwg .Add (1 )
136+ go func () {
137+ cwg .Done ()
138+ p := bufPool .Get ().(* []byte )
139+ defer bufPool .Put (p )
140+ io .CopyBuffer (outw , console , * p )
141+ outw .Close ()
142+ outr .Close ()
143+ wg .Done ()
144+ }()
145+ cwg .Wait ()
57146 }
58- wg .Add (1 )
59- cwg .Add (1 )
60- go func () {
61- cwg .Done ()
62- p := bufPool .Get ().(* []byte )
63- defer bufPool .Put (p )
64-
65- io .CopyBuffer (outw , console , * p )
66- console .Close ()
67- outr .Close ()
68- outw .Close ()
69- wg .Done ()
70- }()
71- cwg .Wait ()
72147 return console , nil
73148}
74149
0 commit comments