@@ -29,17 +29,21 @@ public class Localstack {
2929
3030 private static final int DEFAULT_EDGE_PORT = 4566 ;
3131
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" };
3433
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
3639 private static final Pattern DEFAULT_PORT_PATTERN = Pattern .compile ("'(\\ w+)'\\ Q: '{proto}://{host}:\\ E(\\ d+)'" );
3740
3841 private Container localStackContainer ;
3942
4043 /**
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()
4347 */
4448 private static Map <String , Integer > serviceToPortMap ;
4549
@@ -54,7 +58,8 @@ public class Localstack {
5458 CommonUtils .disableSslCertChecking ();
5559 }
5660
57- private Localstack () { }
61+ private Localstack () {
62+ }
5863
5964 public void startup (LocalstackDockerConfiguration dockerConfiguration ) {
6065 if (locked ) {
@@ -64,19 +69,12 @@ public void startup(LocalstackDockerConfiguration dockerConfiguration) {
6469 this .externalHostName = dockerConfiguration .getExternalHostName ();
6570
6671 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 ());
8078 loadServiceToPortMap ();
8179
8280 LOG .info ("Waiting for LocalStack container to be ready..." );
@@ -87,7 +85,8 @@ public void startup(LocalstackDockerConfiguration dockerConfiguration) {
8785 localStackContainer .waitForLogToken (dockerConfiguration .getInitializationToken ());
8886 }
8987 } 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 ()) {
9190 LOG .info ("Ignoring port conflict when starting Docker container, due to ignoreDockerRunErrors=true" );
9291 localStackContainer = Container .getRunningLocalstackContainer ();
9392 loadServiceToPortMap ();
@@ -110,7 +109,25 @@ public boolean isRunning() {
110109 }
111110
112111 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+ }
114131
115132 int edgePort = getEdgePort ();
116133 Map <String , Integer > ports = new RegexStream (DEFAULT_PORT_PATTERN .matcher (localStackPortConfig )).stream ()
@@ -122,10 +139,11 @@ private void loadServiceToPortMap() {
122139 public String getEndpointS3 () {
123140 String s3Endpoint = endpointForService (ServiceName .S3 );
124141 /*
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)
129147 */
130148 s3Endpoint = s3Endpoint .replace ("localhost" , Constants .LOCALHOST_DOMAIN_NAME );
131149 return s3Endpoint ;
@@ -139,7 +157,7 @@ public int getEdgePort() {
139157 public String getEndpointKinesis () {
140158 return endpointForService (ServiceName .KINESIS );
141159 }
142-
160+
143161 public String getEndpointKMS () {
144162 return endpointForService (ServiceName .KMS );
145163 }
0 commit comments