Procházet zdrojové kódy

Add Refresh() to Sandbox

- Convinience API which detaches the sandbox from
  all endpoints, resets and reapply config options,
  setup discovery files, reattach to the endpoints.
  No change to the osl sandbox in use.

Signed-off-by: Alessandro Boch <aboch@docker.com>
Alessandro Boch před 10 roky
rodič
revize
b0dd4944f5
3 změnil soubory, kde provedl 68 přidání a 20 odebrání
  1. 1 12
      libnetwork/controller.go
  2. 4 0
      libnetwork/libnetwork_test.go
  3. 63 8
      libnetwork/sandbox.go

+ 1 - 12
libnetwork/controller.go

@@ -410,18 +410,7 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
 
 	sb.processOptions(options...)
 
-	err = sb.buildHostsFile()
-	if err != nil {
-		return nil, err
-	}
-
-	err = sb.updateParentHosts()
-	if err != nil {
-		return nil, err
-	}
-
-	err = sb.setupDNS()
-	if err != nil {
+	if err = sb.setupResolutionFiles(); err != nil {
 		return nil, err
 	}
 

+ 4 - 0
libnetwork/libnetwork_test.go

@@ -1180,6 +1180,10 @@ func (f *fakeSandbox) Statistics() (map[string]*osl.InterfaceStatistics, error)
 	return nil, nil
 }
 
+func (f *fakeSandbox) Refresh(opts ...libnetwork.SandboxOption) error {
+	return nil
+}
+
 func (f *fakeSandbox) Delete() error {
 	return nil
 }

+ 63 - 8
libnetwork/sandbox.go

@@ -29,6 +29,9 @@ type Sandbox interface {
 	Labels() map[string]interface{}
 	// Statistics retrieves the interfaces' statistics for the sandbox
 	Statistics() (map[string]*osl.InterfaceStatistics, error)
+	// Refresh leaves all the endpoints, resets and re-apply the options,
+	// re-joins all the endpoints without destroying the osl sandbox
+	Refresh(options ...SandboxOption) error
 	// Delete destroys this container after detaching it from all connected endpoints.
 	Delete() error
 }
@@ -139,16 +142,10 @@ func (sb *sandbox) Statistics() (map[string]*osl.InterfaceStatistics, error) {
 }
 
 func (sb *sandbox) Delete() error {
-	sb.Lock()
 	c := sb.controller
-	eps := make([]*endpoint, len(sb.endpoints))
-	for i, ep := range sb.endpoints {
-		eps[i] = ep
-	}
-	sb.Unlock()
 
-	// Detach from all containers
-	for _, ep := range eps {
+	// Detach from all endpoints
+	for _, ep := range sb.getConnectedEndpoints() {
 		if err := ep.Leave(sb); err != nil {
 			log.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
 		}
@@ -165,6 +162,36 @@ func (sb *sandbox) Delete() error {
 	return nil
 }
 
+func (sb *sandbox) Refresh(options ...SandboxOption) error {
+	// Store connected endpoints
+	epList := sb.getConnectedEndpoints()
+
+	// Detach from all endpoints
+	for _, ep := range epList {
+		if err := ep.Leave(sb); err != nil {
+			log.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
+		}
+	}
+
+	// Re-apply options
+	sb.config = containerConfig{}
+	sb.processOptions(options...)
+
+	// Setup discovery files
+	if err := sb.setupResolutionFiles(); err != nil {
+		return err
+	}
+
+	// Re -connect to all endpoints
+	for _, ep := range epList {
+		if err := ep.Join(sb); err != nil {
+			log.Warnf("Failed attach sandbox %s to endpoint %s: %v\n", sb.ID(), ep.ID(), err)
+		}
+	}
+
+	return nil
+}
+
 func (sb *sandbox) MarshalJSON() ([]byte, error) {
 	sb.Lock()
 	defer sb.Unlock()
@@ -185,6 +212,34 @@ func (sb *sandbox) UnmarshalJSON(b []byte) (err error) {
 	return nil
 }
 
+func (sb *sandbox) setupResolutionFiles() error {
+	if err := sb.buildHostsFile(); err != nil {
+		return err
+	}
+
+	if err := sb.updateParentHosts(); err != nil {
+		return err
+	}
+
+	if err := sb.setupDNS(); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (sb *sandbox) getConnectedEndpoints() []*endpoint {
+	sb.Lock()
+	defer sb.Unlock()
+
+	eps := make([]*endpoint, len(sb.endpoints))
+	for i, ep := range sb.endpoints {
+		eps[i] = ep
+	}
+
+	return eps
+}
+
 func (sb *sandbox) updateGateway(ep *endpoint) error {
 	sb.osSbox.UnsetGateway()
 	sb.osSbox.UnsetGatewayIPv6()