@@ -29,17 +29,21 @@ public class Localstack {
29
29
30
30
private static final int DEFAULT_EDGE_PORT = 4566 ;
31
31
32
- private static final String PORT_CONFIG_FILENAME = "/opt/code/localstack/" +
33
- ".venv/lib/python3.8/site-packages/localstack_client/config.py" ;
32
+ private static final String [] PYTHON_VERSIONS_FOLDERS = { "python3.8" , "python3.7" };
34
33
35
- //Regular expression used to parse localstack config to determine default ports for services
34
+ private static final String PORT_CONFIG_FILENAME = "/opt/code/localstack/"
35
+ + ".venv/lib/%s/site-packages/localstack_client/config.py" ;
36
+
37
+ // Regular expression used to parse localstack config to determine default ports
38
+ // for services
36
39
private static final Pattern DEFAULT_PORT_PATTERN = Pattern .compile ("'(\\ w+)'\\ Q: '{proto}://{host}:\\ E(\\ d+)'" );
37
40
38
41
private Container localStackContainer ;
39
42
40
43
/**
41
- * This is a mapping from service name to internal ports. In order to use them, the
42
- * internal port must be resolved to an external docker port via Container.getExternalPortFor()
44
+ * This is a mapping from service name to internal ports. In order to use them,
45
+ * the internal port must be resolved to an external docker port via
46
+ * Container.getExternalPortFor()
43
47
*/
44
48
private static Map <String , Integer > serviceToPortMap ;
45
49
@@ -54,7 +58,8 @@ public class Localstack {
54
58
CommonUtils .disableSslCertChecking ();
55
59
}
56
60
57
- private Localstack () { }
61
+ private Localstack () {
62
+ }
58
63
59
64
public void startup (LocalstackDockerConfiguration dockerConfiguration ) {
60
65
if (locked ) {
@@ -64,19 +69,12 @@ public void startup(LocalstackDockerConfiguration dockerConfiguration) {
64
69
this .externalHostName = dockerConfiguration .getExternalHostName ();
65
70
66
71
try {
67
- localStackContainer = Container .createLocalstackContainer (
68
- dockerConfiguration .getExternalHostName (),
69
- dockerConfiguration .isPullNewImage (),
70
- dockerConfiguration .isRandomizePorts (),
71
- dockerConfiguration .getImageName (),
72
- dockerConfiguration .getImageTag (),
73
- dockerConfiguration .getPortEdge (),
74
- dockerConfiguration .getPortElasticSearch (),
75
- dockerConfiguration .getEnvironmentVariables (),
76
- dockerConfiguration .getPortMappings (),
77
- dockerConfiguration .getBindMounts (),
78
- dockerConfiguration .getPlatform ()
79
- );
72
+ localStackContainer = Container .createLocalstackContainer (dockerConfiguration .getExternalHostName (),
73
+ dockerConfiguration .isPullNewImage (), dockerConfiguration .isRandomizePorts (),
74
+ dockerConfiguration .getImageName (), dockerConfiguration .getImageTag (),
75
+ dockerConfiguration .getPortEdge (), dockerConfiguration .getPortElasticSearch (),
76
+ dockerConfiguration .getEnvironmentVariables (), dockerConfiguration .getPortMappings (),
77
+ dockerConfiguration .getBindMounts (), dockerConfiguration .getPlatform ());
80
78
loadServiceToPortMap ();
81
79
82
80
LOG .info ("Waiting for LocalStack container to be ready..." );
@@ -87,7 +85,8 @@ public void startup(LocalstackDockerConfiguration dockerConfiguration) {
87
85
localStackContainer .waitForLogToken (dockerConfiguration .getInitializationToken ());
88
86
}
89
87
} catch (Exception t ) {
90
- if (t .toString ().contains ("port is already allocated" ) && dockerConfiguration .isIgnoreDockerRunErrors ()) {
88
+ if ((t .toString ().contains ("port is already allocated" ) || t .toString ().contains ("address already in use" ))
89
+ && dockerConfiguration .isIgnoreDockerRunErrors ()) {
91
90
LOG .info ("Ignoring port conflict when starting Docker container, due to ignoreDockerRunErrors=true" );
92
91
localStackContainer = Container .getRunningLocalstackContainer ();
93
92
loadServiceToPortMap ();
@@ -110,7 +109,25 @@ public boolean isRunning() {
110
109
}
111
110
112
111
private void loadServiceToPortMap () {
113
- String localStackPortConfig = localStackContainer .executeCommand (Arrays .asList ("cat" , PORT_CONFIG_FILENAME ));
112
+ String localStackPortConfig = "" ;
113
+ for (int i = 0 ; i < PYTHON_VERSIONS_FOLDERS .length ; i ++) {
114
+ String filePath = String .format (PORT_CONFIG_FILENAME , PYTHON_VERSIONS_FOLDERS [i ]);
115
+
116
+ localStackPortConfig = localStackContainer .executeCommand (Arrays .asList ("cat" , filePath ));
117
+ if (localStackPortConfig .contains ("No such container" )){
118
+ localStackPortConfig = "" ;
119
+ continue ;
120
+ }else if (localStackPortConfig .contains ("No such file" )){
121
+ localStackPortConfig = "" ;
122
+ continue ;
123
+ }else {
124
+ break ;
125
+ }
126
+ }
127
+
128
+ if (localStackPortConfig .isEmpty ()){
129
+ throw new LocalstackDockerException ("No config file found" ,new Exception ());
130
+ }
114
131
115
132
int edgePort = getEdgePort ();
116
133
Map <String , Integer > ports = new RegexStream (DEFAULT_PORT_PATTERN .matcher (localStackPortConfig )).stream ()
@@ -122,10 +139,11 @@ private void loadServiceToPortMap() {
122
139
public String getEndpointS3 () {
123
140
String s3Endpoint = endpointForService (ServiceName .S3 );
124
141
/*
125
- * Use the domain name wildcard *.localhost.localstack.cloud which maps to 127.0.0.1
126
- * We need to do this because S3 SDKs attempt to access a domain <bucket-name>.<service-host-name>
127
- * which by default would result in <bucket-name>.localhost, but that name cannot be resolved
128
- * (unless hardcoded in /etc/hosts)
142
+ * Use the domain name wildcard *.localhost.localstack.cloud which maps to
143
+ * 127.0.0.1 We need to do this because S3 SDKs attempt to access a domain
144
+ * <bucket-name>.<service-host-name> which by default would result in
145
+ * <bucket-name>.localhost, but that name cannot be resolved (unless hardcoded
146
+ * in /etc/hosts)
129
147
*/
130
148
s3Endpoint = s3Endpoint .replace ("localhost" , Constants .LOCALHOST_DOMAIN_NAME );
131
149
return s3Endpoint ;
@@ -139,7 +157,7 @@ public int getEdgePort() {
139
157
public String getEndpointKinesis () {
140
158
return endpointForService (ServiceName .KINESIS );
141
159
}
142
-
160
+
143
161
public String getEndpointKMS () {
144
162
return endpointForService (ServiceName .KMS );
145
163
}
0 commit comments