@@ -15,6 +15,7 @@ import (
1515"regexp"
1616"sort"
1717"strconv"
18+ "strings"
1819"sync"
1920"sync/atomic"
2021"time"
@@ -41,6 +42,7 @@ const (
4142maxNumberOfPortsToCheck = 5
4243portCheckingTimeout = 3 * time .Second
4344unknownVersion = "unknown"
45+ wildcardIP = "0.0.0.0"
4446)
4547
4648// PortPool describes an available port range for clones.
@@ -73,11 +75,12 @@ type Provisioner struct {
7375pm * pool.Manager
7476networkID string
7577instanceID string
78+ gateway string
7679}
7780
7881// New creates a new Provisioner instance.
7982func New (ctx context.Context ,cfg * Config ,dbCfg * resources.DB ,docker * client.Client ,pm * pool.Manager ,
80- instanceID ,networkID string ) (* Provisioner ,error ) {
83+ instanceID ,networkID , gateway string ) (* Provisioner ,error ) {
8184if err := IsValidConfig (* cfg );err != nil {
8285return nil ,errors .Wrap (err ,"configuration is not valid" )
8386}
@@ -93,6 +96,7 @@ func New(ctx context.Context, cfg *Config, dbCfg *resources.DB, docker *client.C
9396pm :pm ,
9497networkID :networkID ,
9598instanceID :instanceID ,
99+ gateway :gateway ,
96100ports :make ([]bool ,cfg .PortPool .To - cfg .PortPool .From + 1 ),
97101}
98102
@@ -435,7 +439,7 @@ func getLatestSnapshot(snapshots []resources.Snapshot) (*resources.Snapshot, err
435439func (p * Provisioner )RevisePortPool ()error {
436440log .Msg (fmt .Sprintf ("Revising availability of the port range [%d - %d]" ,p .config .PortPool .From ,p .config .PortPool .To ))
437441
438- host ,err := externalIP ( )
442+ host ,err := hostIP ( p . gateway )
439443if err != nil {
440444return err
441445}
@@ -468,13 +472,21 @@ func (p *Provisioner) RevisePortPool() error {
468472return nil
469473}
470474
475+ func hostIP (gateway string ) (string ,error ) {
476+ if gateway != "" {
477+ return gateway ,nil
478+ }
479+
480+ return externalIP ()
481+ }
482+
471483// allocatePort tries to find a free port and occupy it.
472484func (p * Provisioner )allocatePort () (uint ,error ) {
473485portOpts := p .config .PortPool
474486
475487attempts := 0
476488
477- host ,err := externalIP ( )
489+ host ,err := hostIP ( p . gateway )
478490if err != nil {
479491return 0 ,err
480492}
@@ -598,6 +610,8 @@ func (p *Provisioner) stopPoolSessions(fsm pool.FSManager, exceptClones map[stri
598610}
599611
600612func (p * Provisioner )getAppConfig (pool * resources.Pool ,name string ,port uint )* resources.AppConfig {
613+ provisionHosts := p .getProvisionHosts ()
614+
601615appConfig := & resources.AppConfig {
602616CloneName :name ,
603617DockerImage :p .config .DockerImage ,
@@ -607,12 +621,33 @@ func (p *Provisioner) getAppConfig(pool *resources.Pool, name string, port uint)
607621Pool :pool ,
608622ContainerConf :p .config .ContainerConfig ,
609623NetworkID :p .networkID ,
610- ProvisionHosts :p . config . CloneAccessAddresses ,
624+ ProvisionHosts :provisionHosts ,
611625}
612626
613627return appConfig
614628}
615629
630+ // getProvisionHosts adds an internal Docker gateway to the hosts rule if the user restricts access to IP addresses.
631+ func (p * Provisioner )getProvisionHosts ()string {
632+ provisionHosts := p .config .CloneAccessAddresses
633+
634+ if provisionHosts == "" || provisionHosts == wildcardIP {
635+ return provisionHosts
636+ }
637+
638+ hostSet := []string {p .gateway }
639+
640+ for _ ,hostIP := range strings .Split (provisionHosts ,"," ) {
641+ if hostIP != p .gateway {
642+ hostSet = append (hostSet ,hostIP )
643+ }
644+ }
645+
646+ provisionHosts = strings .Join (hostSet ,"," )
647+
648+ return provisionHosts
649+ }
650+
616651// LastSessionActivity returns the time of the last session activity.
617652func (p * Provisioner )LastSessionActivity (session * resources.Session ,minimumTime time.Time ) (* time.Time ,error ) {
618653fsm ,err := p .pm .GetFSManager (session .Pool )