github.com/containerd/Containerd@v1.4.13/cmd/ctr/commands/tasks/tasks_unix.go (about) 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 tasks 20 21 import ( 22 gocontext "context" 23 "net/url" 24 "os" 25 "os/signal" 26 27 "github.com/containerd/console" 28 "github.com/containerd/containerd" 29 "github.com/containerd/containerd/cio" 30 "github.com/containerd/containerd/log" 31 "github.com/pkg/errors" 32 "github.com/urfave/cli" 33 "golang.org/x/sys/unix" 34 ) 35 36 func init() { 37 startCommand.Flags = append(startCommand.Flags, cli.BoolFlag{ 38 Name: "no-pivot", 39 Usage: "disable use of pivot-root (linux only)", 40 }) 41 } 42 43 // HandleConsoleResize resizes the console 44 func HandleConsoleResize(ctx gocontext.Context, task resizer, con console.Console) error { 45 // do an initial resize of the console 46 size, err := con.Size() 47 if err != nil { 48 return err 49 } 50 if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil { 51 log.G(ctx).WithError(err).Error("resize pty") 52 } 53 s := make(chan os.Signal, 16) 54 signal.Notify(s, unix.SIGWINCH) 55 go func() { 56 for range s { 57 size, err := con.Size() 58 if err != nil { 59 log.G(ctx).WithError(err).Error("get pty size") 60 continue 61 } 62 if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil { 63 log.G(ctx).WithError(err).Error("resize pty") 64 } 65 } 66 }() 67 return nil 68 } 69 70 // NewTask creates a new task 71 func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, con console.Console, nullIO bool, logURI string, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) { 72 stdinC := &stdinCloser{ 73 stdin: os.Stdin, 74 } 75 stdio := cio.NewCreator(append([]cio.Opt{cio.WithStreams(stdinC, os.Stdout, os.Stderr)}, ioOpts...)...) 76 if checkpoint != "" { 77 im, err := client.GetImage(ctx, checkpoint) 78 if err != nil { 79 return nil, err 80 } 81 opts = append(opts, containerd.WithTaskCheckpoint(im)) 82 } 83 ioCreator := stdio 84 if con != nil { 85 ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStreams(con, con, nil), cio.WithTerminal}, ioOpts...)...) 86 } 87 if nullIO { 88 if con != nil { 89 return nil, errors.New("tty and null-io cannot be used together") 90 } 91 ioCreator = cio.NullIO 92 } 93 if logURI != "" { 94 u, err := url.Parse(logURI) 95 if err != nil { 96 return nil, err 97 } 98 ioCreator = cio.LogURI(u) 99 } 100 t, err := container.NewTask(ctx, ioCreator, opts...) 101 if err != nil { 102 return nil, err 103 } 104 stdinC.closer = func() { 105 t.CloseIO(ctx, containerd.WithStdinCloser) 106 } 107 return t, nil 108 } 109 110 func getNewTaskOpts(context *cli.Context) []containerd.NewTaskOpts { 111 if context.Bool("no-pivot") { 112 return []containerd.NewTaskOpts{containerd.WithNoPivotRoot} 113 } 114 return nil 115 }