@@ -100,6 +100,9 @@ type NetworkController interface {
100100 // SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned.
101101 SandboxByID (id string ) (Sandbox , error )
102102
103+ // SandboxDestroy destroys a sandbox given a container ID
104+ SandboxDestroy (id string ) error
105+
103106 // Stop network controller
104107 Stop ()
105108}
@@ -144,6 +147,8 @@ type controller struct {
144147 unWatchCh chan * endpoint
145148 svcDb map [string ]svcMap
146149 nmap map [string ]* netWatch
150+ defOsSbox osl.Sandbox
151+ sboxOnce sync.Once
147152 sync.Mutex
148153}
149154
@@ -476,27 +481,37 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
476481 return nil , types .BadRequestErrorf ("invalid container ID" )
477482 }
478483
479- var existing Sandbox
480- look := SandboxContainerWalker (& existing , containerID )
481- c .WalkSandboxes (look )
482- if existing != nil {
483- return nil , types .BadRequestErrorf ("container %s is already present: %v" , containerID , existing )
484+ var sb * sandbox
485+ c .Lock ()
486+ for _ , s := range c .sandboxes {
487+ if s .containerID == containerID {
488+ // If not a stub, then we already have a complete sandbox.
489+ if ! s .isStub {
490+ c .Unlock ()
491+ return nil , types .BadRequestErrorf ("container %s is already present: %v" , containerID , s )
492+ }
493+
494+ // We already have a stub sandbox from the
495+ // store. Make use of it so that we don't lose
496+ // the endpoints from store but reset the
497+ // isStub flag.
498+ sb = s
499+ sb .isStub = false
500+ break
501+ }
484502 }
503+ c .Unlock ()
485504
486505 // Create sandbox and process options first. Key generation depends on an option
487- sb := & sandbox {
488- id : stringid .GenerateRandomID (),
489- containerID : containerID ,
490- endpoints : epHeap {},
491- epPriority : map [string ]int {},
492- config : containerConfig {},
493- controller : c ,
494- }
495- // This sandbox may be using an existing osl sandbox, sharing it with another sandbox
496- var peerSb Sandbox
497- c .WalkSandboxes (SandboxKeyWalker (& peerSb , sb .Key ()))
498- if peerSb != nil {
499- sb .osSbox = peerSb .(* sandbox ).osSbox
506+ if sb == nil {
507+ sb = & sandbox {
508+ id : stringid .GenerateRandomID (),
509+ containerID : containerID ,
510+ endpoints : epHeap {},
511+ epPriority : map [string ]int {},
512+ config : containerConfig {},
513+ controller : c ,
514+ }
500515 }
501516
502517 heap .Init (& sb .endpoints )
@@ -507,14 +522,26 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
507522 return nil , err
508523 }
509524
510- c .Lock ()
525+ if sb .config .useDefaultSandBox {
526+ c .sboxOnce .Do (func () {
527+ c .defOsSbox , err = osl .NewSandbox (sb .Key (), false )
528+ })
529+
530+ if err != nil {
531+ c .sboxOnce = sync.Once {}
532+ return nil , fmt .Errorf ("failed to create default sandbox: %v" , err )
533+ }
534+
535+ sb .osSbox = c .defOsSbox
536+ }
537+
511538 if sb .osSbox == nil && ! sb .config .useExternalKey {
512539 if sb .osSbox , err = osl .NewSandbox (sb .Key (), ! sb .config .useDefaultSandBox ); err != nil {
513- c .Unlock ()
514540 return nil , fmt .Errorf ("failed to create new osl sandbox: %v" , err )
515541 }
516542 }
517543
544+ c .Lock ()
518545 c .sandboxes [sb .id ] = sb
519546 c .Unlock ()
520547 defer func () {
@@ -539,6 +566,11 @@ func (c *controller) Sandboxes() []Sandbox {
539566
540567 list := make ([]Sandbox , 0 , len (c .sandboxes ))
541568 for _ , s := range c .sandboxes {
569+ // Hide stub sandboxes from libnetwork users
570+ if s .isStub {
571+ continue
572+ }
573+
542574 list = append (list , s )
543575 }
544576
@@ -566,6 +598,26 @@ func (c *controller) SandboxByID(id string) (Sandbox, error) {
566598 return s , nil
567599}
568600
601+ // SandboxDestroy destroys a sandbox given a container ID
602+ func (c * controller ) SandboxDestroy (id string ) error {
603+ var sb * sandbox
604+ c .Lock ()
605+ for _ , s := range c .sandboxes {
606+ if s .containerID == id {
607+ sb = s
608+ break
609+ }
610+ }
611+ c .Unlock ()
612+
613+ // It is not an error if sandbox is not available
614+ if sb == nil {
615+ return nil
616+ }
617+
618+ return sb .Delete ()
619+ }
620+
569621// SandboxContainerWalker returns a Sandbox Walker function which looks for an existing Sandbox with the passed containerID
570622func SandboxContainerWalker (out * Sandbox , containerID string ) SandboxWalker {
571623 return func (sb Sandbox ) bool {
0 commit comments