77 "fmt"
88 "os"
99 "path/filepath"
10+ "strings"
1011 "sync"
1112 "text/template"
1213 "time"
@@ -20,9 +21,10 @@ import (
2021)
2122
2223const (
23- DefaultHTTPPort = "6688"
24- DefaultP2PPort = "6690"
25- TmpImageName = "chainlink-tmp:latest"
24+ DefaultHTTPPort = "6688"
25+ DefaultP2PPort = "6690"
26+ TmpImageName = "chainlink-tmp:latest"
27+ CustomPortSeparator = ":"
2628)
2729
2830var (
@@ -51,7 +53,7 @@ type NodeInput struct {
5153 UserSecretsOverrides string `toml:"user_secrets_overrides"`
5254 HTTPPort int `toml:"port"`
5355 P2PPort int `toml:"p2p_port"`
54- CustomPorts []int `toml:"custom_ports"`
56+ CustomPorts []string `toml:"custom_ports"`
5557}
5658
5759// Output represents Chainlink node output, nodes and databases connection URLs
@@ -111,6 +113,54 @@ func NewNode(in *Input, pgOut *postgres.Output) (*Output, error) {
111113 return out , nil
112114}
113115
116+ // generatePortBindings generates exposed ports and port bindings
117+ // exposes default CL node port
118+ // exposes custom_ports in format "host:docker" or map 1-to-1 if only "host" port is provided
119+ func generatePortBindings (in * Input ) ([]string , nat.PortMap , error ) {
120+ httpPort := fmt .Sprintf ("%s/tcp" , DefaultHTTPPort )
121+ portBindings := nat.PortMap {
122+ nat .Port (httpPort ): []nat.PortBinding {
123+ {
124+ HostIP : "0.0.0.0" ,
125+ HostPort : fmt .Sprintf ("%d/tcp" , in .Node .HTTPPort ),
126+ },
127+ },
128+ }
129+ customPorts := make ([]string , 0 )
130+ for _ , p := range in .Node .CustomPorts {
131+ if strings .Contains (p , CustomPortSeparator ) {
132+ pp := strings .Split (p , CustomPortSeparator )
133+ if len (pp ) != 2 {
134+ return nil , nil , errors .New ("custom_ports has ':' but you must provide both ports" )
135+ }
136+ customPorts = append (customPorts , fmt .Sprintf ("%s/tcp" , pp [1 ]))
137+
138+ dockerPort := nat .Port (fmt .Sprintf ("%s/tcp" , pp [1 ]))
139+ hostPort := fmt .Sprintf ("%s/tcp" , pp [0 ])
140+ portBindings [dockerPort ] = []nat.PortBinding {
141+ {
142+ HostIP : "0.0.0.0" ,
143+ HostPort : hostPort ,
144+ },
145+ }
146+ } else {
147+ customPorts = append (customPorts , fmt .Sprintf ("%s/tcp" , p ))
148+
149+ dockerPort := nat .Port (fmt .Sprintf ("%s/tcp" , p ))
150+ hostPort := fmt .Sprintf ("%s/tcp" , p )
151+ portBindings [dockerPort ] = []nat.PortBinding {
152+ {
153+ HostIP : "0.0.0.0" ,
154+ HostPort : hostPort ,
155+ },
156+ }
157+ }
158+ }
159+ exposedPorts := []string {httpPort }
160+ exposedPorts = append (exposedPorts , customPorts ... )
161+ return exposedPorts , portBindings , nil
162+ }
163+
114164func newNode (in * Input , pgOut * postgres.Output ) (* NodeOut , error ) {
115165 ctx := context .Background ()
116166
@@ -147,37 +197,17 @@ func newNode(in *Input, pgOut *postgres.Output) (*NodeOut, error) {
147197 return nil , err
148198 }
149199
150- httpPort := fmt .Sprintf ("%s/tcp" , DefaultHTTPPort )
151200 var containerName string
152201 if in .Node .Name != "" {
153202 containerName = in .Node .Name
154203 } else {
155204 containerName = framework .DefaultTCName ("node" )
156205 }
157- customPorts := make ([]string , 0 )
158- for _ , p := range in .Node .CustomPorts {
159- customPorts = append (customPorts , fmt .Sprintf ("%d/tcp" , p ))
160- }
161- exposedPorts := []string {httpPort }
162- exposedPorts = append (exposedPorts , customPorts ... )
163206
164- portBindings := nat.PortMap {
165- nat .Port (httpPort ): []nat.PortBinding {
166- {
167- HostIP : "0.0.0.0" ,
168- HostPort : fmt .Sprintf ("%d/tcp" , in .Node .HTTPPort ),
169- },
170- },
171- }
172- for _ , p := range customPorts {
173- portBindings [nat .Port (p )] = []nat.PortBinding {
174- {
175- HostIP : "0.0.0.0" ,
176- HostPort : p ,
177- },
178- }
207+ exposedPorts , portBindings , err := generatePortBindings (in )
208+ if err != nil {
209+ return nil , err
179210 }
180-
181211 req := tc.ContainerRequest {
182212 AlwaysPullImage : in .Node .PullImage ,
183213 Image : in .Node .Image ,
0 commit comments