@@ -2,149 +2,37 @@ package main
22
33import (
44 gocontext "context"
5- "encoding/json"
6- "fmt"
7- "io/ioutil"
85 "time"
96
107 "github.com/Sirupsen/logrus"
118 "github.com/containerd/console"
129 "github.com/containerd/containerd"
13- "github.com/containerd/containerd/api/services/tasks/v1 "
10+ "github.com/containerd/containerd/errdefs "
1411 "github.com/containerd/containerd/log"
15- "github.com/containerd/containerd/mount"
16- "github.com/containerd/containerd/windows"
17- "github.com/containerd/containerd/windows/hcs"
1812 digest "github.com/opencontainers/go-digest"
19- ocispec "github.com/opencontainers/image-spec/specs-go/v1"
2013 specs "github.com/opencontainers/runtime-spec/specs-go"
14+ "github.com/pkg/errors"
2115 "github.com/urfave/cli"
2216)
2317
2418const pipeRoot = `\\.\pipe`
2519
2620func init () {
2721 runCommand .Flags = append (runCommand .Flags , cli.StringSliceFlag {
28- Name : "layers " ,
22+ Name : "layer " ,
2923 Usage : "HCSSHIM Layers to be used" ,
3024 })
3125}
3226
33- func spec (id string , config * ocispec.ImageConfig , context * cli.Context ) * specs.Spec {
34- cmd := config .Cmd
35- if a := context .Args ().First (); a != "" {
36- cmd = context .Args ()
37- }
38-
39- var (
40- // TODO: support overriding entrypoint
41- args = append (config .Entrypoint , cmd ... )
42- tty = context .Bool ("tty" )
43- cwd = config .WorkingDir
44- )
45-
46- if cwd == "" {
47- cwd = `C:\`
48- }
49-
50- // Some sane defaults for console
51- w := 80
52- h := 20
53-
54- if tty {
55- con := console .Current ()
56- size , err := con .Size ()
57- if err == nil {
58- w = int (size .Width )
59- h = int (size .Height )
27+ func withLayers (context * cli.Context ) containerd.SpecOpts {
28+ return func (s * specs.Spec ) error {
29+ l := context .StringSlice ("layer" )
30+ if l == nil {
31+ return errors .Wrap (errdefs .ErrInvalidArgument , "base layers must be specified with `--layer`" )
6032 }
33+ s .Windows .LayerFolders = l
34+ return nil
6135 }
62-
63- env := replaceOrAppendEnvValues (config .Env , context .StringSlice ("env" ))
64-
65- return & specs.Spec {
66- Version : specs .Version ,
67- Root : & specs.Root {
68- Readonly : context .Bool ("readonly" ),
69- },
70- Process : & specs.Process {
71- Args : args ,
72- Terminal : tty ,
73- Cwd : cwd ,
74- Env : env ,
75- User : specs.User {
76- Username : config .User ,
77- },
78- ConsoleSize : & specs.Box {
79- Height : uint (w ),
80- Width : uint (h ),
81- },
82- },
83- Hostname : id ,
84- }
85- }
86-
87- func customSpec (context * cli.Context , configPath , rootfs string ) (* specs.Spec , error ) {
88- b , err := ioutil .ReadFile (configPath )
89- if err != nil {
90- return nil , err
91- }
92-
93- var s specs.Spec
94- if err := json .Unmarshal (b , & s ); err != nil {
95- return nil , err
96- }
97-
98- if rootfs != "" && s .Root .Path != rootfs {
99- logrus .Warnf ("ignoring config Root.Path %q, setting %q forcibly" , s .Root .Path , rootfs )
100- s .Root .Path = rootfs
101- }
102- return & s , nil
103- }
104-
105- func getConfig (context * cli.Context , imageConfig * ocispec.ImageConfig , rootfs string ) (* specs.Spec , error ) {
106- if config := context .String ("runtime-config" ); config != "" {
107- return customSpec (context , config , rootfs )
108- }
109-
110- s := spec (context .String ("id" ), imageConfig , context )
111- if rootfs != "" {
112- s .Root .Path = rootfs
113- }
114-
115- return s , nil
116- }
117-
118- func newContainerSpec (context * cli.Context , config * ocispec.ImageConfig , imageRef string ) ([]byte , error ) {
119- spec , err := getConfig (context , config , context .String ("rootfs" ))
120- if err != nil {
121- return nil , err
122- }
123- if spec .Annotations == nil {
124- spec .Annotations = make (map [string ]string )
125- }
126- spec .Annotations ["image" ] = imageRef
127- rtSpec := windows.RuntimeSpec {
128- OCISpec : * spec ,
129- Configuration : hcs.Configuration {
130- Layers : context .StringSlice ("layers" ),
131- IgnoreFlushesDuringBoot : true ,
132- AllowUnqualifiedDNSQuery : true },
133- }
134- return json .Marshal (rtSpec )
135- }
136-
137- func newCreateTaskRequest (context * cli.Context , id , tmpDir string , checkpoint * ocispec.Descriptor , mounts []mount.Mount ) (* tasks.CreateTaskRequest , error ) {
138- create := & tasks.CreateTaskRequest {
139- ContainerID : id ,
140- Terminal : context .Bool ("tty" ),
141- Stdin : fmt .Sprintf (`%s\ctr-%s-stdin` , pipeRoot , id ),
142- Stdout : fmt .Sprintf (`%s\ctr-%s-stdout` , pipeRoot , id ),
143- }
144- if ! create .Terminal {
145- create .Stderr = fmt .Sprintf (`%s\ctr-%s-stderr` , pipeRoot , id )
146- }
147- return create , nil
14836}
14937
15038func handleConsoleResize (ctx gocontext.Context , task resizer , con console.Console ) error {
@@ -175,7 +63,14 @@ func handleConsoleResize(ctx gocontext.Context, task resizer, con console.Consol
17563 return nil
17664}
17765
178- func withTTY () containerd.SpecOpts {
66+ func withTTY (terminal bool ) containerd.SpecOpts {
67+ if ! terminal {
68+ return func (s * specs.Spec ) error {
69+ s .Process .Terminal = false
70+ return nil
71+ }
72+ }
73+
17974 con := console .Current ()
18075 size , err := con .Size ()
18176 if err != nil {
@@ -192,43 +87,37 @@ func newContainer(ctx gocontext.Context, client *containerd.Client, context *cli
19287 var (
19388 err error
19489
195- ref = context .Args ().First ()
196- id = context .Args ().Get (1 )
197- args = context .Args ()[2 :]
198- tty = context .Bool ("tty" )
90+ // ref = context.Args().First()
91+ id = context .Args ().Get (1 )
92+ args = context .Args ()[2 :]
93+ tty = context .Bool ("tty" )
94+ labelStrings = context .StringSlice ("label" )
19995 )
200- image , err := client .GetImage (ctx , ref )
201- if err != nil {
202- return nil , err
203- }
96+
97+ labels := labelArgs (labelStrings )
98+
99+ // TODO(mlaventure): get base image once we have a snapshotter
100+
204101 opts := []containerd.SpecOpts {
205- containerd .WithImageConfig (ctx , image ),
102+ // TODO(mlaventure): use containerd.WithImageConfig once we have a snapshotter
103+ withLayers (context ),
206104 withEnv (context ),
207105 withMounts (context ),
106+ withTTY (tty ),
208107 }
209108 if len (args ) > 0 {
210109 opts = append (opts , containerd .WithProcessArgs (args ... ))
211110 }
212- if tty {
213- opts = append (opts , withTTY ())
214- }
215- if context .Bool ("net-host" ) {
216- opts = append (opts , setHostNetworking ())
217- }
111+
218112 spec , err := containerd .GenerateSpec (opts ... )
219113 if err != nil {
220114 return nil , err
221115 }
222- var rootfs containerd.NewContainerOpts
223- if context .Bool ("readonly" ) {
224- rootfs = containerd .WithNewReadonlyRootFS (id , image )
225- } else {
226- rootfs = containerd .WithNewRootFS (id , image )
227- }
116+
228117 return client .NewContainer (ctx , id ,
229118 containerd .WithSpec (spec ),
230- containerd .WithImage ( image ),
231- rootfs ,
119+ containerd .WithContainerLabels ( labels ),
120+ // TODO(mlaventure): containerd.WithImage(image) ,
232121 )
233122}
234123
0 commit comments