@@ -25,12 +25,14 @@ import (
2525 "github.com/alibaba/pouch/pkg/collect"
2626 "github.com/alibaba/pouch/pkg/errtypes"
2727 "github.com/alibaba/pouch/pkg/meta"
28+ mountutils "github.com/alibaba/pouch/pkg/mount"
2829 "github.com/alibaba/pouch/pkg/randomid"
2930 "github.com/alibaba/pouch/pkg/utils"
3031 "github.com/alibaba/pouch/storage/quota"
3132 volumetypes "github.com/alibaba/pouch/storage/volume/types"
3233
3334 "github.com/containerd/containerd/errdefs"
35+ "github.com/containerd/containerd/mount"
3436 "github.com/containerd/containerd/namespaces"
3537 "github.com/docker/libnetwork"
3638 "github.com/go-openapi/strfmt"
@@ -597,14 +599,24 @@ func (mgr *ContainerManager) createContainerdContainer(ctx context.Context, c *C
597599
598600 c .Lock ()
599601 ctrdContainer := & ctrd.Container {
600- ID : c .ID ,
601- Image : c .Config .Image ,
602- Runtime : c .HostConfig .Runtime ,
603- Spec : sw .s ,
604- IO : io ,
602+ ID : c .ID ,
603+ Image : c .Config .Image ,
604+ Runtime : c .HostConfig .Runtime ,
605+ Spec : sw .s ,
606+ IO : io ,
607+ RootFSProvided : c .RootFSProvided ,
608+ BaseFS : c .BaseFS ,
605609 }
606610 c .Unlock ()
607611
612+ // if creating the container by specified the rootfs, we must check
613+ // whether the rootfs is mounted before creation
614+ if c .RootFSProvided {
615+ if err := mgr .ensureRootFSMounted (c .BaseFS , c .Snapshotter .Data ); err != nil {
616+ return fmt .Errorf ("failed to mount container rootfs: %v" , err )
617+ }
618+ }
619+
608620 if err := mgr .Client .CreateContainer (ctx , ctrdContainer ); err != nil {
609621 logrus .Errorf ("failed to create new containerd container: %v" , err )
610622
@@ -631,6 +643,53 @@ func (mgr *ContainerManager) createContainerdContainer(ctx context.Context, c *C
631643 return c .Write (mgr .Store )
632644}
633645
646+ func (mgr * ContainerManager ) ensureRootFSMounted (rootfs string , snapData map [string ]string ) error {
647+ if rootfs == "" || len (snapData ) == 0 {
648+ return fmt .Errorf ("container rootfs or snapshotter data is empty" )
649+ }
650+
651+ // check if rootfs already mounted
652+ notMounted , err := mountutils .IsLikelyNotMountPoint (rootfs )
653+ if err != nil {
654+ return err
655+ }
656+ // rootfs already mounted
657+ if ! notMounted {
658+ return nil
659+ }
660+
661+ var workDir , upperDir , lowerDir string
662+ for _ , dir := range []string {"WorkDir" , "UpperDir" , "LowerDir" } {
663+ if v , ok := snapData [dir ]; ok {
664+ switch dir {
665+ case "WorkDir" :
666+ workDir = v
667+ case "UpperDir" :
668+ upperDir = v
669+ case "LowerDir" :
670+ lowerDir = v
671+ }
672+ }
673+ }
674+
675+ if workDir == "" || upperDir == "" || lowerDir == "" {
676+ return fmt .Errorf ("faile to mount overlay: one or more dirs in WorkDir, UpperDir and LowerDir are empty" )
677+ }
678+
679+ options := []string {
680+ fmt .Sprintf ("workdir=%s" , snapData ["WorkDir" ]),
681+ fmt .Sprintf ("upperdir=%s" , snapData ["UpperDir" ]),
682+ fmt .Sprintf ("lowerdir=%s" , snapData ["LowerDir" ]),
683+ }
684+ mount := mount.Mount {
685+ Type : "overlay" ,
686+ Source : "overlay" ,
687+ Options : options ,
688+ }
689+
690+ return mount .Mount (rootfs )
691+ }
692+
634693// Stop stops a running container.
635694func (mgr * ContainerManager ) Stop (ctx context.Context , name string , timeout int64 ) error {
636695 c , err := mgr .container (name )
@@ -949,9 +1008,13 @@ func (mgr *ContainerManager) Remove(ctx context.Context, name string, options *t
9491008 logrus .Errorf ("failed to detach volume: %v" , err )
9501009 }
9511010
952- // remove snapshot
953- if err := mgr .Client .RemoveSnapshot (ctx , c .ID ); err != nil {
954- logrus .Errorf ("failed to remove snapshot of container %s: %v" , c .ID , err )
1011+ // if creating the container by specify rootfs,
1012+ // there is no snapshot for this container.
1013+ if ! c .RootFSProvided {
1014+ // remove snapshot
1015+ if err := mgr .Client .RemoveSnapshot (ctx , c .ID ); err != nil {
1016+ logrus .Errorf ("failed to remove snapshot of container %s: %v" , c .ID , err )
1017+ }
9551018 }
9561019
9571020 // When removing a container, we have set up such rule for object removing sequences:
@@ -967,7 +1030,6 @@ func (mgr *ContainerManager) Remove(ctx context.Context, name string, options *t
9671030 if err := mgr .Store .Remove (c .Key ()); err != nil {
9681031 logrus .Errorf ("failed to remove container %s from meta store: %v" , c .ID , err )
9691032 }
970-
9711033 return nil
9721034}
9731035
0 commit comments