@@ -26,12 +26,14 @@ import (
2626 "github.com/alibaba/pouch/pkg/collect"
2727 "github.com/alibaba/pouch/pkg/errtypes"
2828 "github.com/alibaba/pouch/pkg/meta"
29+ mountutils "github.com/alibaba/pouch/pkg/mount"
2930 "github.com/alibaba/pouch/pkg/randomid"
3031 "github.com/alibaba/pouch/pkg/utils"
3132 "github.com/alibaba/pouch/storage/quota"
3233 volumetypes "github.com/alibaba/pouch/storage/volume/types"
3334
3435 "github.com/containerd/containerd/errdefs"
36+ "github.com/containerd/containerd/mount"
3537 "github.com/containerd/containerd/namespaces"
3638 "github.com/docker/libnetwork"
3739 "github.com/go-openapi/strfmt"
@@ -571,14 +573,24 @@ func (mgr *ContainerManager) createContainerdContainer(ctx context.Context, c *C
571573
572574 c .Lock ()
573575 ctrdContainer := & ctrd.Container {
574- ID : c .ID ,
575- Image : c .Config .Image ,
576- Runtime : c .HostConfig .Runtime ,
577- Spec : sw .s ,
578- IO : io ,
576+ ID : c .ID ,
577+ Image : c .Config .Image ,
578+ Runtime : c .HostConfig .Runtime ,
579+ Spec : sw .s ,
580+ IO : io ,
581+ RootFSProvided : c .RootFSProvided ,
582+ BaseFS : c .BaseFS ,
579583 }
580584 c .Unlock ()
581585
586+ // if creating the container by specified the rootfs, we must check
587+ // whether the rootfs is mounted before creation
588+ if c .RootFSProvided {
589+ if err := mgr .ensureRootFSMounted (c .BaseFS , c .Snapshotter .Data ); err != nil {
590+ return fmt .Errorf ("failed to mount container rootfs: %v" , err )
591+ }
592+ }
593+
582594 if err := mgr .Client .CreateContainer (ctx , ctrdContainer ); err != nil {
583595 logrus .Errorf ("failed to create new containerd container: %v" , err )
584596
@@ -605,6 +617,53 @@ func (mgr *ContainerManager) createContainerdContainer(ctx context.Context, c *C
605617 return c .Write (mgr .Store )
606618}
607619
620+ func (mgr * ContainerManager ) ensureRootFSMounted (rootfs string , snapData map [string ]string ) error {
621+ if rootfs == "" || len (snapData ) == 0 {
622+ return fmt .Errorf ("container rootfs or snapshotter data is empty" )
623+ }
624+
625+ // check if rootfs already mounted
626+ notMounted , err := mountutils .IsLikelyNotMountPoint (rootfs )
627+ if err != nil {
628+ return err
629+ }
630+ // rootfs already mounted
631+ if ! notMounted {
632+ return nil
633+ }
634+
635+ var workDir , upperDir , lowerDir string
636+ for _ , dir := range []string {"WorkDir" , "UpperDir" , "LowerDir" } {
637+ if v , ok := snapData [dir ]; ok {
638+ switch dir {
639+ case "WorkDir" :
640+ workDir = v
641+ case "UpperDir" :
642+ upperDir = v
643+ case "LowerDir" :
644+ lowerDir = v
645+ }
646+ }
647+ }
648+
649+ if workDir == "" || upperDir == "" || lowerDir == "" {
650+ return fmt .Errorf ("faile to mount overlay: one or more dirs in WorkDir, UpperDir and LowerDir are empty" )
651+ }
652+
653+ options := []string {
654+ fmt .Sprintf ("workdir=%s" , snapData ["WorkDir" ]),
655+ fmt .Sprintf ("upperdir=%s" , snapData ["UpperDir" ]),
656+ fmt .Sprintf ("lowerdir=%s" , snapData ["LowerDir" ]),
657+ }
658+ mount := mount.Mount {
659+ Type : "overlay" ,
660+ Source : "overlay" ,
661+ Options : options ,
662+ }
663+
664+ return mount .Mount (rootfs )
665+ }
666+
608667// Stop stops a running container.
609668func (mgr * ContainerManager ) Stop (ctx context.Context , name string , timeout int64 ) error {
610669 c , err := mgr .container (name )
@@ -934,9 +993,13 @@ func (mgr *ContainerManager) Remove(ctx context.Context, name string, options *t
934993 // remove container cache
935994 mgr .cache .Remove (c .ID )
936995
937- // remove snapshot
938- if err := mgr .Client .RemoveSnapshot (ctx , c .ID ); err != nil {
939- logrus .Errorf ("failed to remove snapshot of container %s: %v" , c .ID , err )
996+ // if creating the container by specify rootfs,
997+ // there is no snapshot for this container.
998+ if ! c .RootFSProvided {
999+ // remove snapshot
1000+ if err := mgr .Client .RemoveSnapshot (ctx , c .ID ); err != nil {
1001+ logrus .Errorf ("failed to remove snapshot of container %s: %v" , c .ID , err )
1002+ }
9401003 }
9411004
9421005 return nil
0 commit comments