Docker #46

Merged
bmartin5692 merged 4 commits from docker into master 2019-06-15 07:15:24 +02:00
5 changed files with 110 additions and 53 deletions

19
Dockerfile Normal file
View file

@ -0,0 +1,19 @@
FROM python:3.7-alpine as base
FROM base as builder
RUN mkdir /install
WORKDIR /install
COPY requirements.txt /requirements.txt
RUN pip install --install-option="--prefix=/install" -r /requirements.txt
FROM base
COPY --from=builder /install /usr/local
COPY . /bumper
WORKDIR /bumper
ENTRYPOINT ["python3", "-m", "bumper"]

View file

@ -94,6 +94,44 @@ Bumper has a number of available command-line arguments that can be viewed by ad
Bumper looks for a number of Environment Variables at initialization allowing for customizing a number of settings. For more information see the [Environment Variables](docs/Env_Var.md) doc. Bumper looks for a number of Environment Variables at initialization allowing for customizing a number of settings. For more information see the [Environment Variables](docs/Env_Var.md) doc.
## Docker
### Docker build
To build the docker image you can run the following:
`docker build -t bumper .`
This requires Docker 17.09 or newer, but has also been tested with podman.
### Docker usage
To run the image in docker some environment settings and port mappings are required:
**Ports Required: (-p)**
- 443 - `-p 443:443`
- 8007 - `-p 8007:8007`
- 8883 - `-p 8883:8883`
- 5223 - `-p 5223:5223`
**Environment Settings: (-e)**
BUMPER_ANNOUNCE_IP should be used so the actual host IP is reported to bots that checkin.
- BUMPER_ANNOUNCE_IP - `-e "BUMPER_ANNOUNCE_IP=X.X.X.X"`
**Volume Settings: (-v)**
Optionally you can map existing directories for logs, data, and certs.
- data/logs/certs
- Data - `-v /home/user/bumper/data:/bumper/data`
**Full Example:**
````
docker run -it -e "BUMPER_ANNOUNCE_IP=X.X.X.X" -p 443:443 -p 8007:8007 -p 8883:8883 -p 5223:5223 -v /home/user/bumper/data:/bumper/data --name bumper bumper
````
## Thanks ## Thanks
A big thanks to the original project creator @torbjornaxelsson, without his work this project would have taken much longer to build. A big thanks to the original project creator @torbjornaxelsson, without his work this project would have taken much longer to build.

View file

@ -23,23 +23,29 @@ def strtobool(strbool):
# os.environ['PYTHONASYNCIODEBUG'] = '1' # Uncomment to enable ASYNCIODEBUG # os.environ['PYTHONASYNCIODEBUG'] = '1' # Uncomment to enable ASYNCIODEBUG
bumper_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) bumper_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
# Set defaults from environment variables first
# Certs
ca_cert = os.environ.get("BUMPER_CA") or os.path.join(bumper_dir, "certs", "ca.crt")
server_cert = os.environ.get("BUMPER_CERT") or os.path.join(
bumper_dir, "certs", "bumper.crt"
)
server_key = os.environ.get("BUMPER_KEY") or os.path.join(
bumper_dir, "certs", "bumper.key"
)
# Set defaults from environment variables first
print(bumper_dir)
# Folders # Folders
logs_dir = os.environ.get("BUMPER_LOGS") or os.path.join(bumper_dir, "logs") logs_dir = os.environ.get("BUMPER_LOGS") or os.path.join(bumper_dir, "logs")
os.makedirs(logs_dir, exist_ok=True) # Ensure logs directory exists or create os.makedirs(logs_dir, exist_ok=True) # Ensure logs directory exists or create
print(logs_dir)
data_dir = os.environ.get("BUMPER_DATA") or os.path.join(bumper_dir, "data") data_dir = os.environ.get("BUMPER_DATA") or os.path.join(bumper_dir, "data")
os.makedirs(data_dir, exist_ok=True) # Ensure data directory exists or create os.makedirs(data_dir, exist_ok=True) # Ensure data directory exists or create
print(data_dir)
certs_dir = os.environ.get("BUMPER_CERTS") or os.path.join(bumper_dir, "certs")
os.makedirs(certs_dir, exist_ok=True) # Ensure data directory exists or create
print(certs_dir)
# Certs
ca_cert = os.environ.get("BUMPER_CA") or os.path.join(certs_dir, "ca.crt")
print(ca_cert)
server_cert = os.environ.get("BUMPER_CERT") or os.path.join(certs_dir, "bumper.crt")
print(server_cert)
server_key = os.environ.get("BUMPER_KEY") or os.path.join(certs_dir, "bumper.key")
print(server_key)
# Listeners # Listeners
bumper_listen = os.environ.get("BUMPER_LISTEN") or socket.gethostbyname( bumper_listen = os.environ.get("BUMPER_LISTEN") or socket.gethostbyname(
@ -113,6 +119,7 @@ xmppserverlog.addHandler(xmpp_rotate)
logging.getLogger("asyncio").setLevel(logging.CRITICAL + 1) # Ignore this logger logging.getLogger("asyncio").setLevel(logging.CRITICAL + 1) # Ignore this logger
mqtt_listen_port = 8883 mqtt_listen_port = 8883
conf1_listen_port = 443 conf1_listen_port = 443
conf2_listen_port = 8007 conf2_listen_port = 8007
@ -970,6 +977,7 @@ def create_certs():
subprocess.run([os.path.join("..", "create_certs", "create_certs_linux")]) subprocess.run([os.path.join("..", "create_certs", "create_certs_linux")])
else: else:
os.chdir(odir)
logging.log( logging.log(
logging.FATAL, logging.FATAL,
"Can't determine platform. Create certs manually and try again.", "Can't determine platform. Create certs manually and try again.",
@ -988,25 +996,9 @@ def create_certs():
os.execv(sys.executable, ["python"] + sys.argv) # Start again os.execv(sys.executable, ["python"] + sys.argv) # Start again
def firstrun_input():
return input(
"No certificates found, would you like to create them automatically? (y/n): "
).lower()
def first_run(): def first_run():
yes = {"yes", "y", "ye", ""}
print("")
if firstrun_input() in yes:
create_certs() create_certs()
else:
logging.log(
logging.FATAL,
"Can't continue without certificates, please create some then try again.",
)
def main(argv=None): def main(argv=None):
import argparse import argparse

16
requirements.txt Normal file
View file

@ -0,0 +1,16 @@
-i https://pypi.python.org/simple
aiohttp==4.0.0a0
async-timeout==3.0.1
attrs==19.1.0
chardet==3.0.4
docopt==0.6.2
hbmqtt==0.9.5
idna==2.8
multidict==4.5.2
passlib==1.7.1
pyyaml==5.1.1
six==1.12.0
tinydb==3.13.0
transitions==0.6.9
websockets==7.0
yarl==1.3.0

View file

@ -13,29 +13,10 @@ from testfixtures import LogCapture
import sys import sys
@patch("bumper.firstrun_input")
@patch("bumper.create_certs")
def test_firstrun(mock_input, mock_create):
with LogCapture() as l:
bumper.firstrun_input.return_value = "n"
bumper.first_run()
l.check_present(
(
"root",
"CRITICAL",
"Can't continue without certificates, please create some then try again.",
)
)
bumper.firstrun_input.return_value = "y"
bumper.first_run()
assert mock_create.called == True
def mock_subrun(*args): def mock_subrun(*args):
return args return args
@patch("bumper.start") @patch("bumper.start")
def test_argparse(mock_start): def test_argparse(mock_start):
bumper.ca_cert = "tests/test_certs/ca.crt" bumper.ca_cert = "tests/test_certs/ca.crt"
@ -70,23 +51,35 @@ def test_createcert(mock_run, mock_platform, mock_machine, mock_exec):
platform.system.return_value = "darwin" platform.system.return_value = "darwin"
bumper.create_certs() bumper.create_certs()
assert mock_run.called == True assert mock_run.called == True
assert os.path.join("..", "create_certs", "create_certs_osx") in mock_exec.call_args.args[0] assert (
os.path.join("..", "create_certs", "create_certs_osx")
in mock_exec.call_args.args[0]
)
platform.system.return_value = "windows" platform.system.return_value = "windows"
bumper.create_certs() bumper.create_certs()
assert mock_run.called == True assert mock_run.called == True
assert os.path.join("..", "create_certs", "create_certs_windows.exe") in mock_exec.call_args.args[0] assert (
os.path.join("..", "create_certs", "create_certs_windows.exe")
in mock_exec.call_args.args[0]
)
platform.system.return_value = "linux" platform.system.return_value = "linux"
bumper.create_certs() bumper.create_certs()
assert mock_run.called == True assert mock_run.called == True
assert os.path.join("..", "create_certs","create_certs_linux") in mock_exec.call_args.args[0] assert (
os.path.join("..", "create_certs", "create_certs_linux")
in mock_exec.call_args.args[0]
)
platform.system.return_value = "linux" platform.system.return_value = "linux"
platform.machine.return_value = "arm" platform.machine.return_value = "arm"
bumper.create_certs() bumper.create_certs()
assert mock_run.called == True assert mock_run.called == True
assert os.path.join("..", "create_certs", "create_certs_rpi") in mock_exec.call_args.args[0] assert (
os.path.join("..", "create_certs", "create_certs_rpi")
in mock_exec.call_args.args[0]
)
with LogCapture() as l: with LogCapture() as l:
platform.system.return_value = "nixbad" platform.system.return_value = "nixbad"
@ -101,7 +94,6 @@ def test_createcert(mock_run, mock_platform, mock_machine, mock_exec):
) )
@patch("bumper.first_run") @patch("bumper.first_run")
def test_main(mock_firstrun): def test_main(mock_firstrun):
bumper.ca_cert = "sf" bumper.ca_cert = "sf"