Repository: localstack/localstack

Issue:
bug: `in_docker()` can open `/etc/hostname` without checking it exists
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

When running localstack not in docker, but in an environment where `/proc/1/cgroup` exists, `in_docker()` at https://github.com/localstack/localstack/blob/d806081ab4994b8805251388e1f66140b96eb46a/localstack/config.py#L565 attempts to open `/etc/hostname` without any checks for its existence. In an environment where it does not exist, the code exits with an error instead of proceeding.

### Expected Behavior

`in_docker()` should either proceed without checking for hostname in `content`, or get the hostname from a safer canonical source, such as:

```python
import socket
hostname = socket.gethostname()
```


### How are you starting LocalStack?

With the `localstack` script

### Steps To Reproduce

#### How are you starting localstack (e.g., `bin/localstack` command, arguments, or `docker-compose.yml`)

```ruby
  LOCAL_STACK = ProcessHelper::ProcessHelper.new(print_lines: true)
  LOCAL_STACK.start(
    ['pipenv', 'run', 'env', 'SERVICES=sns,sqs,s3', 'localstack', 'start', '--host'],
    /Ready/,
    60
  )
```

#### Client commands (e.g., AWS SDK code snippet, or sequence of "awslocal" commands)

Failure occurs in `config.py` before any client commands get a chance to run.


### Environment

```markdown
- OS: CentOS Linux release 7.9.2009 (Core)
- LocalStack: 0.13.0.9
```


### Anything else?

Output on failure, from Jenkins:
```
11:22:13      __                     _______ __             __
11:22:13     / /   ____  _________ _/ / ___// /_____ ______/ /__
11:22:13    / /   / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
11:22:13   / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
11:22:13  /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|
11:22:13 
11:22:13  💻 LocalStack CLI 0.13.0.9
11:22:13 
11:22:16 Traceback (most recent call last):
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/bin/localstack", line 23, in <module>
11:22:16     main()
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/bin/localstack", line 19, in main
11:22:16     main.main()
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/localstack/cli/main.py", line 6, in main
11:22:16     cli()
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/localstack/cli/plugin.py", line 15, in __call__
11:22:16     self.group(*args, **kwargs)
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/click/core.py", line 1128, in __call__
11:22:16     return self.main(*args, **kwargs)
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/click/core.py", line 1053, in main
11:22:16     rv = self.invoke(ctx)
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/click/core.py", line 1659, in invoke
11:22:16     return _process_result(sub_ctx.command.invoke(sub_ctx))
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/click/core.py", line 1395, in invoke
11:22:16     return ctx.invoke(self.callback, **ctx.params)
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/click/core.py", line 754, in invoke
11:22:16     return __callback(*args, **kwargs)
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/localstack/cli/localstack.py", line 105, in cmd_start
11:22:16     from localstack.utils import bootstrap
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/localstack/utils/bootstrap.py", line 11, in <module>
11:22:16     from localstack import config, constants
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/localstack/config.py", line 572, in <module>
11:22:16     is_in_docker = in_docker()
11:22:16   File "/home/jenkins/.local/share/virtualenvs/dsl.python_cosmos_lambda.distiller.build-uIfsvcZ_/lib/python3.7/site-packages/localstack/config.py", line 565, in in_docker
11:22:16     os_hostname = open("/etc/hostname", "rt").read().strip()
11:22:16 FileNotFoundError: [Errno 2] No such file or directory: '/etc/hostname'
11:22:16 EOF encountered while waiting for output that matches '(?-mix:Ready)' (RuntimeError)
```


Discussion:

Resolving patch:
diff --git a/localstack/config.py b/localstack/config.py
--- a/localstack/config.py
+++ b/localstack/config.py
@@ -590,9 +590,11 @@ def in_docker():
     except Exception:
         pass
     with open("/proc/1/cgroup", "rt") as ifh:
-        os_hostname = open("/etc/hostname", "rt").read().strip()
         content = ifh.read()
-        if os_hostname in content or "docker" in content:
+        if "docker" in content:
+            return True
+        os_hostname = socket.gethostname()
+        if os_hostname and os_hostname in content:
             return True
     return False
 


Test patch: