Repository: localstack/localstack

Issue:
Startup fails with DATA_DIR and kinesis-mock
# Type of request: This is a ...

bug report

# Detailed description

localstack fails to start correctly with `DATA_DIR` and the kinesis-mock kinesis provider

## Expected behavior

localstack should start correctly

## Actual behavior

instead the startup throws error messages like these:

```
76b772e7226f_localstackmain  | 
76b772e7226f_localstackmain  | Traceback (most recent call last):
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/utils/server/http2_server.py", line 129, in index
76b772e7226f_localstackmain  |     raise result
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/utils/bootstrap.py", line 701, in run
76b772e7226f_localstackmain  |     result = self.func(self.params, **kwargs)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/utils/async_utils.py", line 29, in _run
76b772e7226f_localstackmain  |     return fn(*args, **kwargs)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/services/generic_proxy.py", line 428, in handler
76b772e7226f_localstackmain  |     client_address=request.remote_addr, server_address=parsed_url.netloc)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/services/generic_proxy.py", line 244, in modify_and_forward
76b772e7226f_localstackmain  |     listener_result = listener.forward_request(method=method, path=path, data=data, headers=headers)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/services/edge.py", line 122, in forward_request
76b772e7226f_localstackmain  |     return do_forward_request(api, method, path, data, headers, port=port)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/services/edge.py", line 143, in do_forward_request
76b772e7226f_localstackmain  |     result = do_forward_request_inmem(api, method, path, data, headers, port=port)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/services/edge.py", line 165, in do_forward_request_inmem
76b772e7226f_localstackmain  |     client_address=client_address, server_address=server_address)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/localstack/services/generic_proxy.py", line 290, in modify_and_forward
76b772e7226f_localstackmain  |     response = requests.request(method, request_url, data=data_to_send, headers=headers, stream=True, verify=False)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/.venv/lib/python3.7/site-packages/requests/api.py", line 61, in request
76b772e7226f_localstackmain  |     return session.request(method=method, url=url, **kwargs)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/.venv/lib/python3.7/site-packages/requests/sessions.py", line 542, in request
76b772e7226f_localstackmain  |     resp = self.send(prep, **send_kwargs)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/.venv/lib/python3.7/site-packages/requests/sessions.py", line 655, in send
76b772e7226f_localstackmain  |     r = adapter.send(request, **kwargs)
76b772e7226f_localstackmain  |   File "/opt/code/localstack/.venv/lib/python3.7/site-packages/requests/adapters.py", line 516, in send
76b772e7226f_localstackmain  |     raise ConnectionError(e, request=request)
76b772e7226f_localstackmain  | requests.exceptions.ConnectionError: MyHTTPConnectionPool(host='localhost', port=56787): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fbe40c9aed0>: Failed to establish a new connection: [Errno 111] Connection refused'))
76b772e7226f_localstackmain  | 
76b772e7226f_localstackmain  | 2021-06-28T17:54:34:WARNING:localstack.services.plugins: Service "kinesis" not yet available, retrying...
^CGracefully stopping... (press Ctrl+C again to force)
```

# Steps to reproduce

## Command used to start LocalStack

    DATA_DIR=/tmp/localstack/data DEBUG=1 bin/localstack start --host



Discussion:
The root cause is https://github.com/etspaceman/kinesis-mock/issues/129, as kinesis-mock fails to start and then it can't connect to the service

once fixed and released, we should update to kinsesis-mock 0.1.3.

moreover we should consider improving the logging output of the starting procedure. the log output is spammed with unhelpful `ConnectionError` traces.
as a workaround, in older localstack versions, you can use kinesalite as a provider. set the environment variable `KINESIS_PROVIDER=kinesalite`, in `:latest` we have a workaround
I've created #4268 to fix this.
thanks @etspaceman! i'll remove the workaround and test it with the new version.

Resolving patch:
diff --git a/localstack/services/install.py b/localstack/services/install.py
--- a/localstack/services/install.py
+++ b/localstack/services/install.py
@@ -82,7 +82,7 @@
 )
 
 # kinesis-mock version
-KINESIS_MOCK_VERSION = os.environ.get("KINESIS_MOCK_VERSION") or "0.1.2"
+KINESIS_MOCK_VERSION = os.environ.get("KINESIS_MOCK_VERSION") or "0.1.3"
 KINESIS_MOCK_RELEASE_URL = (
     "https://api.github.com/repos/etspaceman/kinesis-mock/releases/tags/" + KINESIS_MOCK_VERSION
 )
diff --git a/localstack/services/kinesis/kinesis_starter.py b/localstack/services/kinesis/kinesis_starter.py
--- a/localstack/services/kinesis/kinesis_starter.py
+++ b/localstack/services/kinesis/kinesis_starter.py
@@ -1,6 +1,4 @@
 import logging
-import os
-import traceback
 
 from localstack import config
 from localstack.constants import MODULE_MAIN_PATH
@@ -11,8 +9,6 @@
 
 LOGGER = logging.getLogger(__name__)
 
-KINESIS_MOCK_RELEASES = "https://api.github.com/repos/etspaceman/kinesis-mock/releases/tags/0.1.3"
-
 
 def apply_patches_kinesalite():
     files = [
@@ -46,13 +42,6 @@ def start_kinesis_mock(port=None, asynchronous=False, update_listener=None):
     if config.DATA_DIR:
         kinesis_data_dir = "%s/kinesis" % config.DATA_DIR
         mkdir(kinesis_data_dir)
-
-        # FIXME: workaround for https://github.com/localstack/localstack/issues/4227
-        streams_file = os.path.join(kinesis_data_dir, "kinesis-data.json")
-        if not os.path.exists(streams_file):
-            with open(streams_file, "w") as fd:
-                fd.write('{"streams":{}}')
-
         kinesis_data_dir_param = "SHOULD_PERSIST_DATA=true PERSIST_PATH=%s" % kinesis_data_dir
     if not config.LS_LOG:
         log_level = "INFO"
@@ -81,7 +70,7 @@ def start_kinesis_mock(port=None, asynchronous=False, update_listener=None):
     )
 
     if config.KINESIS_INITIALIZE_STREAMS != "":
-        initialize_streams_param = "INITIALIZE_STREAMS=%s" % (config.KINESIS_INITIALIZE_STREAMS)
+        initialize_streams_param = "INITIALIZE_STREAMS=%s" % config.KINESIS_INITIALIZE_STREAMS
     else:
         initialize_streams_param = ""
 
@@ -148,7 +137,7 @@ def check_kinesis(expect_shutdown=False, print_error=False):
         out = aws_stack.connect_to_service(service_name="kinesis").list_streams()
     except Exception as e:
         if print_error:
-            LOGGER.error("Kinesis health check failed: %s %s" % (e, traceback.format_exc()))
+            LOGGER.exception("Kinesis health check failed: %s", e)
     if expect_shutdown:
         assert out is None
     else:


Test patch: