RestoreNetwork() allows the container to restore its NetworkSettings (IP
and public ports).
Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
| ... | ... |
@@ -441,7 +441,7 @@ func (container *Container) buildHostnameAndHostsFiles(IP string) error {
|
| 441 | 441 |
return container.buildHostsFiles(IP) |
| 442 | 442 |
} |
| 443 | 443 |
|
| 444 |
-func (container *Container) AllocateNetwork() error {
|
|
| 444 |
+func (container *Container) AllocateNetwork() (err error) {
|
|
| 445 | 445 |
mode := container.hostConfig.NetworkMode |
| 446 | 446 |
if container.Config.NetworkDisabled || !mode.IsPrivate() {
|
| 447 | 447 |
return nil |
| ... | ... |
@@ -449,7 +449,6 @@ func (container *Container) AllocateNetwork() error {
|
| 449 | 449 |
|
| 450 | 450 |
var ( |
| 451 | 451 |
env *engine.Env |
| 452 |
- err error |
|
| 453 | 452 |
eng = container.daemon.eng |
| 454 | 453 |
) |
| 455 | 454 |
|
| ... | ... |
@@ -461,14 +460,21 @@ func (container *Container) AllocateNetwork() error {
|
| 461 | 461 |
return err |
| 462 | 462 |
} |
| 463 | 463 |
|
| 464 |
+ // Error handling: At this point, the interface is allocated so we have to |
|
| 465 |
+ // make sure that it is always released in case of error, otherwise we |
|
| 466 |
+ // might leak resources. |
|
| 467 |
+ defer func() {
|
|
| 468 |
+ if err != nil {
|
|
| 469 |
+ eng.Job("release_interface", container.ID).Run()
|
|
| 470 |
+ } |
|
| 471 |
+ }() |
|
| 472 |
+ |
|
| 464 | 473 |
if container.Config.PortSpecs != nil {
|
| 465 | 474 |
if err := migratePortMappings(container.Config, container.hostConfig); err != nil {
|
| 466 |
- eng.Job("release_interface", container.ID).Run()
|
|
| 467 | 475 |
return err |
| 468 | 476 |
} |
| 469 | 477 |
container.Config.PortSpecs = nil |
| 470 | 478 |
if err := container.WriteHostConfig(); err != nil {
|
| 471 |
- eng.Job("release_interface", container.ID).Run()
|
|
| 472 | 479 |
return err |
| 473 | 480 |
} |
| 474 | 481 |
} |
| ... | ... |
@@ -498,7 +504,6 @@ func (container *Container) AllocateNetwork() error {
|
| 498 | 498 |
|
| 499 | 499 |
for port := range portSpecs {
|
| 500 | 500 |
if err := container.allocatePort(eng, port, bindings); err != nil {
|
| 501 |
- eng.Job("release_interface", container.ID).Run()
|
|
| 502 | 501 |
return err |
| 503 | 502 |
} |
| 504 | 503 |
} |
| ... | ... |
@@ -524,6 +529,37 @@ func (container *Container) ReleaseNetwork() {
|
| 524 | 524 |
container.NetworkSettings = &NetworkSettings{}
|
| 525 | 525 |
} |
| 526 | 526 |
|
| 527 |
+func (container *Container) isNetworkAllocated() bool {
|
|
| 528 |
+ return container.NetworkSettings.IPAddress != "" |
|
| 529 |
+} |
|
| 530 |
+ |
|
| 531 |
+func (container *Container) RestoreNetwork() error {
|
|
| 532 |
+ mode := container.hostConfig.NetworkMode |
|
| 533 |
+ // Don't attempt a restore if we previously didn't allocate networking. |
|
| 534 |
+ // This might be a legacy container with no network allocated, in which case the |
|
| 535 |
+ // allocation will happen once and for all at start. |
|
| 536 |
+ if !container.isNetworkAllocated() || container.Config.NetworkDisabled || !mode.IsPrivate() {
|
|
| 537 |
+ return nil |
|
| 538 |
+ } |
|
| 539 |
+ |
|
| 540 |
+ eng := container.daemon.eng |
|
| 541 |
+ |
|
| 542 |
+ // Re-allocate the interface with the same IP address. |
|
| 543 |
+ job := eng.Job("allocate_interface", container.ID)
|
|
| 544 |
+ job.Setenv("RequestedIP", container.NetworkSettings.IPAddress)
|
|
| 545 |
+ if err := job.Run(); err != nil {
|
|
| 546 |
+ return err |
|
| 547 |
+ } |
|
| 548 |
+ |
|
| 549 |
+ // Re-allocate any previously allocated ports. |
|
| 550 |
+ for port, _ := range container.NetworkSettings.Ports {
|
|
| 551 |
+ if err := container.allocatePort(eng, port, container.NetworkSettings.Ports); err != nil {
|
|
| 552 |
+ return err |
|
| 553 |
+ } |
|
| 554 |
+ } |
|
| 555 |
+ return nil |
|
| 556 |
+} |
|
| 557 |
+ |
|
| 527 | 558 |
// cleanup releases any network resources allocated to the container along with any rules |
| 528 | 559 |
// around how containers are linked together. It also unmounts the container's root filesystem. |
| 529 | 560 |
func (container *Container) cleanup() {
|