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>
This commit is contained in:
Alessandro Boch 2015-09-01 18:55:53 -07:00
parent d05ac74ca7
commit b0dd4944f5
3 changed files with 68 additions and 20 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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()