@@ -21,17 +21,18 @@ import (
2121 "fmt"
2222 "io"
2323 "io/ioutil"
24+ "strings"
2425 "time"
2526
27+ "github.com/containerd/containerd/api/services/execution"
28+ rootfsapi "github.com/containerd/containerd/api/services/rootfs"
2629 prototypes "github.com/gogo/protobuf/types"
2730 "github.com/golang/glog"
31+ imagedigest "github.com/opencontainers/go-digest"
32+ imagespec "github.com/opencontainers/image-spec/specs-go/v1"
2833 runtimespec "github.com/opencontainers/runtime-spec/specs-go"
2934 "github.com/opencontainers/runtime-tools/generate"
3035 "golang.org/x/net/context"
31-
32- "github.com/containerd/containerd/api/services/execution"
33- "github.com/containerd/containerd/api/types/mount"
34-
3536 runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1"
3637
3738 "github.com/kubernetes-incubator/cri-containerd/pkg/metadata"
@@ -81,10 +82,22 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
8182 Config : config ,
8283 }
8384
84- // TODO(random-liu): [P0] Ensure pause image snapshot, apply default image config
85- // and get snapshot mounts.
86- // Use fixed rootfs path and sleep command.
87- const rootPath = "/"
85+ // Ensure sandbox container image snapshot.
86+ imageMeta , err := c .ensureImageExists (ctx , c .sandboxImage )
87+ if err != nil {
88+ return nil , fmt .Errorf ("failed to get sandbox image %q: %v" , defaultSandboxImage , err )
89+ }
90+ prepareResp , err := c .rootfsService .Prepare (ctx , & rootfsapi.PrepareRequest {
91+ Name : id ,
92+ // We are sure that ChainID must be a digest.
93+ ChainID : imagedigest .Digest (imageMeta .ChainID ),
94+ Readonly : true ,
95+ })
96+ if err != nil {
97+ return nil , fmt .Errorf ("failed to prepare sandbox rootfs %q: %v" , imageMeta .ChainID , err )
98+ }
99+ // TODO(random-liu): [P0] Cleanup snapshot on failure after switching to new rootfs api.
100+ rootfsMounts := prepareResp .Mounts
88101
89102 // Create sandbox container root directory.
90103 // Prepare streaming named pipe.
@@ -124,7 +137,10 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
124137 }
125138
126139 // Start sandbox container.
127- spec := c .generateSandboxContainerSpec (id , config )
140+ spec , err := c .generateSandboxContainerSpec (id , config , imageMeta .Config )
141+ if err != nil {
142+ return nil , fmt .Errorf ("failed to generate sandbox container spec: %v" , err )
143+ }
128144 rawSpec , err := json .Marshal (spec )
129145 if err != nil {
130146 return nil , fmt .Errorf ("failed to marshal oci spec %+v: %v" , spec , err )
@@ -137,16 +153,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
137153 Value : rawSpec ,
138154 },
139155 // TODO(random-liu): [P0] Get rootfs mount from containerd.
140- Rootfs : []* mount.Mount {
141- {
142- Type : "bind" ,
143- Source : rootPath ,
144- Options : []string {
145- "rw" ,
146- "rbind" ,
147- },
148- },
149- },
156+ Rootfs : rootfsMounts ,
150157 Runtime : defaultRuntime ,
151158 // No stdin for sandbox container.
152159 Stdout : stdout ,
@@ -205,19 +212,34 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
205212 return & runtime.RunPodSandboxResponse {PodSandboxId : id }, nil
206213}
207214
208- func (c * criContainerdService ) generateSandboxContainerSpec (id string , config * runtime.PodSandboxConfig ) * runtimespec.Spec {
209- // TODO(random-liu): [P0] Get command from image config.
210- pauseCommand := []string {"sh" , "-c" , "while true; do sleep 1000000000; done" }
211-
215+ func (c * criContainerdService ) generateSandboxContainerSpec (id string , config * runtime.PodSandboxConfig ,
216+ imageConfig * imagespec.ImageConfig ) (* runtimespec.Spec , error ) {
212217 // Creates a spec Generator with the default spec.
213218 // TODO(random-liu): [P1] Compare the default settings with docker and containerd default.
214219 g := generate .New ()
215220
216- // Set relative root path.
217- g .SetRootPath (relativeRootfsPath )
221+ // Apply default config from image config.
222+ for _ , e := range imageConfig .Env {
223+ kv := strings .Split (e , "=" )
224+ if len (kv ) != 2 {
225+ return nil , fmt .Errorf ("invalid environment variable in image config %+v" , imageConfig )
226+ }
227+ g .AddProcessEnv (kv [0 ], kv [1 ])
228+ }
218229
230+ if imageConfig .WorkingDir != "" {
231+ g .SetProcessCwd (imageConfig .WorkingDir )
232+ }
233+
234+ if len (imageConfig .Entrypoint ) == 0 {
235+ // Pause image must have entrypoint.
236+ return nil , fmt .Errorf ("invalid empty entrypoint in image config %+v" , imageConfig )
237+ }
219238 // Set process commands.
220- g .SetProcessArgs (pauseCommand )
239+ g .SetProcessArgs (append (imageConfig .Entrypoint , imageConfig .Cmd ... ))
240+
241+ // Set relative root path.
242+ g .SetRootPath (relativeRootfsPath )
221243
222244 // Make root of sandbox container read-only.
223245 g .SetRootReadonly (true )
@@ -276,5 +298,5 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r
276298
277299 // TODO(random-liu): [P1] Set default sandbox container resource limit.
278300
279- return g .Spec ()
301+ return g .Spec (), nil
280302}
0 commit comments