@@ -23,6 +23,7 @@ import (
2323 "io"
2424 "os"
2525 "path"
26+ "path/filepath"
2627 "runtime"
2728 "strings"
2829 "syscall"
@@ -39,9 +40,11 @@ import (
3940 "github.com/containerd/containerd/namespaces"
4041 "github.com/containerd/containerd/oci"
4142 "github.com/containerd/containerd/platforms"
43+ "github.com/containerd/containerd/plugin"
4244 gogotypes "github.com/containerd/containerd/protobuf/types"
4345 _ "github.com/containerd/containerd/runtime"
4446 "github.com/containerd/containerd/runtime/v2/runc/options"
47+ "github.com/containerd/continuity/fs"
4548 "github.com/containerd/go-runc"
4649 "github.com/containerd/typeurl/v2"
4750 specs "github.com/opencontainers/runtime-spec/specs-go"
@@ -173,6 +176,130 @@ func TestContainerStart(t *testing.T) {
173176 }
174177}
175178
179+ func readShimPath (taskID string ) (string , error ) {
180+ runtime := fmt .Sprintf ("%s.%s" , plugin .RuntimePluginV2 , "task" )
181+ shimBinaryNamePath := filepath .Join (defaultState , runtime , testNamespace , taskID , "shim-binary-path" )
182+
183+ shimPath , err := os .ReadFile (shimBinaryNamePath )
184+ if err != nil {
185+ return "" , err
186+ }
187+ return string (shimPath ), nil
188+ }
189+
190+ func copyShim (shimPath string ) (string , error ) {
191+ tempPath := filepath .Join (os .TempDir (), filepath .Base (shimPath ))
192+ if err := fs .CopyFile (tempPath , shimPath ); err != nil {
193+ return "" , err
194+ }
195+
196+ fi , err := os .Stat (shimPath )
197+ if err != nil {
198+ return "" , err
199+ }
200+ if err := os .Chmod (tempPath , fi .Mode ().Perm ()); err != nil {
201+ return "" , err
202+ }
203+
204+ return tempPath , nil
205+ }
206+
207+ func TestContainerStartWithAbsRuntimePath (t * testing.T ) {
208+ t .Parallel ()
209+
210+ client , err := newClient (t , address )
211+ if err != nil {
212+ t .Fatal (err )
213+ }
214+ defer client .Close ()
215+
216+ var (
217+ image Image
218+ ctx , cancel = testContext (t )
219+ id = t .Name ()
220+ )
221+ defer cancel ()
222+
223+ image , err = client .GetImage (ctx , testImage )
224+ if err != nil {
225+ t .Fatal (err )
226+ }
227+ container , err := client .NewContainer (ctx , id , WithNewSnapshot (id , image ), WithNewSpec (oci .WithImageConfig (image ), withExitStatus (7 )))
228+ if err != nil {
229+ t .Fatal (err )
230+ }
231+ defer container .Delete (ctx , WithSnapshotCleanup )
232+
233+ // create a temp task to read the default shim path
234+ task , err := container .NewTask (ctx , empty ())
235+ if err != nil {
236+ t .Fatal (err )
237+ }
238+
239+ defaultShimPath , err := readShimPath (task .ID ())
240+ if err != nil {
241+ t .Fatal (err )
242+ }
243+
244+ // remove the temp task
245+ if _ , err := task .Delete (ctx , WithProcessKill ); err != nil {
246+ t .Fatal (err )
247+ }
248+
249+ tempShimPath , err := copyShim (defaultShimPath )
250+ if err != nil {
251+ t .Fatal (err )
252+ }
253+ defer os .Remove (tempShimPath )
254+
255+ task , err = container .NewTask (ctx , empty (), WithRuntimePath (tempShimPath ))
256+ if err != nil {
257+ t .Fatal (err )
258+ }
259+
260+ shimPath , err := readShimPath (task .ID ())
261+ if err != nil {
262+ t .Fatal (err )
263+ }
264+ if shimPath != tempShimPath {
265+ t .Fatalf ("The task's shim path is %s, does not used the specified runtime path: %s" , shimPath , tempShimPath )
266+ }
267+
268+ statusC , err := task .Wait (ctx )
269+ if err != nil {
270+ t .Fatal (err )
271+ }
272+
273+ if runtime .GOOS != "windows" {
274+ // task.Pid not implemented on Windows
275+ if pid := task .Pid (); pid < 1 {
276+ t .Errorf ("invalid task pid %d" , pid )
277+ }
278+ }
279+
280+ if err := task .Start (ctx ); err != nil {
281+ t .Error (err )
282+ task .Delete (ctx )
283+ return
284+ }
285+ status := <- statusC
286+ code , _ , err := status .Result ()
287+ if err != nil {
288+ t .Fatal (err )
289+ }
290+ if code != 7 {
291+ t .Errorf ("expected status 7 from wait but received %d" , code )
292+ }
293+
294+ deleteStatus , err := task .Delete (ctx )
295+ if err != nil {
296+ t .Fatal (err )
297+ }
298+ if ec := deleteStatus .ExitCode (); ec != 7 {
299+ t .Errorf ("expected status 7 from delete but received %d" , ec )
300+ }
301+ }
302+
176303func TestContainerOutput (t * testing.T ) {
177304 t .Parallel ()
178305
0 commit comments