Merge pull request #1549 from guardicore/docker_data_dir_fix
Docker data dir fix
This commit is contained in:
commit
b91120a677
|
@ -18,6 +18,7 @@ COPY --from=builder /monkey /monkey
|
||||||
WORKDIR /monkey
|
WORKDIR /monkey
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
EXPOSE 5001
|
EXPOSE 5001
|
||||||
|
ENV MONKEY_DOCKER_CONTAINER=true
|
||||||
RUN groupadd -r monkey-island && useradd --no-log-init -r -g monkey-island monkey-island
|
RUN groupadd -r monkey-island && useradd --no-log-init -r -g monkey-island monkey-island
|
||||||
RUN chmod 444 /monkey/monkey_island/cc/server.key
|
RUN chmod 444 /monkey/monkey_island/cc/server.key
|
||||||
RUN chmod 444 /monkey/monkey_island/cc/server.csr
|
RUN chmod 444 /monkey/monkey_island/cc/server.csr
|
||||||
|
|
|
@ -70,7 +70,8 @@ def _setup_data_dir(island_args: IslandCmdArgs) -> Tuple[IslandConfigOptions, st
|
||||||
except json.JSONDecodeError as ex:
|
except json.JSONDecodeError as ex:
|
||||||
print(f"Error loading server config: {ex}")
|
print(f"Error loading server config: {ex}")
|
||||||
exit(1)
|
exit(1)
|
||||||
except IncompatibleDataDirectory:
|
except IncompatibleDataDirectory as ex:
|
||||||
|
print(f"Incompatible data directory: {ex}")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from pathlib import Path
|
||||||
|
|
||||||
from common.version import get_version
|
from common.version import get_version
|
||||||
from monkey_island.cc.server_utils.file_utils import create_secure_directory
|
from monkey_island.cc.server_utils.file_utils import create_secure_directory
|
||||||
|
from monkey_island.cc.setup.env_utils import is_running_on_docker
|
||||||
from monkey_island.cc.setup.version_file_setup import get_version_from_dir, write_version
|
from monkey_island.cc.setup.version_file_setup import get_version_from_dir, write_version
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -26,24 +27,46 @@ def setup_data_dir(data_dir_path: Path) -> None:
|
||||||
|
|
||||||
def _is_data_dir_old(data_dir_path: Path) -> bool:
|
def _is_data_dir_old(data_dir_path: Path) -> bool:
|
||||||
dir_exists = data_dir_path.exists()
|
dir_exists = data_dir_path.exists()
|
||||||
if not dir_exists or not os.listdir(data_dir_path):
|
|
||||||
|
if is_running_on_docker():
|
||||||
|
return _is_docker_data_dir_old(data_dir_path)
|
||||||
|
|
||||||
|
if not dir_exists or _is_directory_empty(data_dir_path):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return _data_dir_version_mismatch_exists(data_dir_path)
|
return _data_dir_version_mismatch_exists(data_dir_path)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_docker_data_dir_old(data_dir_path: Path) -> bool:
|
||||||
|
if _data_dir_version_mismatch_exists(data_dir_path):
|
||||||
|
if _is_directory_empty(data_dir_path):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
raise IncompatibleDataDirectory(
|
||||||
|
"Found an old volume. "
|
||||||
|
"You must create an empty volume for each docker container "
|
||||||
|
"as specified in setup documentation: "
|
||||||
|
"https://www.guardicore.com/infectionmonkey/docs/setup/docker/"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _is_directory_empty(path: Path) -> bool:
|
||||||
|
return not os.listdir(path)
|
||||||
|
|
||||||
|
|
||||||
def _handle_old_data_directory(data_dir_path: Path) -> None:
|
def _handle_old_data_directory(data_dir_path: Path) -> None:
|
||||||
should_delete_data_directory = _prompt_user_to_delete_data_directory(data_dir_path)
|
should_delete_data_directory = _prompt_user_to_delete_data_directory(data_dir_path)
|
||||||
if should_delete_data_directory:
|
if should_delete_data_directory:
|
||||||
shutil.rmtree(data_dir_path)
|
shutil.rmtree(data_dir_path)
|
||||||
logger.info(f"{data_dir_path} was deleted.")
|
logger.info(f"{data_dir_path} was deleted.")
|
||||||
else:
|
else:
|
||||||
logger.error(
|
raise IncompatibleDataDirectory(
|
||||||
"Unable to set up data directory. Please backup and delete the existing data directory"
|
"Unable to set up data directory. Please backup and delete the existing data directory"
|
||||||
f" ({data_dir_path}). Then, try again. To learn how to restore and use a backup, please"
|
f" ({data_dir_path}). Then, try again. To learn how to restore and use a backup, please"
|
||||||
" refer to the documentation."
|
" refer to the documentation."
|
||||||
)
|
)
|
||||||
raise IncompatibleDataDirectory()
|
|
||||||
|
|
||||||
|
|
||||||
def _prompt_user_to_delete_data_directory(data_dir_path: Path) -> bool:
|
def _prompt_user_to_delete_data_directory(data_dir_path: Path) -> bool:
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Must match evn var name in build_scripts/docker/Dockerfile:21
|
||||||
|
DOCKER_ENV_VAR = "MONKEY_DOCKER_CONTAINER"
|
||||||
|
|
||||||
|
|
||||||
|
def is_running_on_docker():
|
||||||
|
return os.environ.get(DOCKER_ENV_VAR) == "true"
|
|
@ -3,6 +3,7 @@ from pathlib import Path
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from monkey_island.cc.setup.data_dir import IncompatibleDataDirectory, setup_data_dir
|
from monkey_island.cc.setup.data_dir import IncompatibleDataDirectory, setup_data_dir
|
||||||
|
from monkey_island.cc.setup.env_utils import DOCKER_ENV_VAR
|
||||||
from monkey_island.cc.setup.version_file_setup import _version_filename
|
from monkey_island.cc.setup.version_file_setup import _version_filename
|
||||||
|
|
||||||
current_version = "1.1.1"
|
current_version = "1.1.1"
|
||||||
|
@ -27,6 +28,12 @@ def temp_version_file_path(temp_data_dir_path) -> Path:
|
||||||
return temp_data_dir_path / _version_filename
|
return temp_data_dir_path / _version_filename
|
||||||
|
|
||||||
|
|
||||||
|
def create_bogus_file(dir_path: Path) -> Path:
|
||||||
|
bogus_file_path = dir_path / "test.txt"
|
||||||
|
bogus_file_path.touch()
|
||||||
|
return bogus_file_path
|
||||||
|
|
||||||
|
|
||||||
def test_setup_data_dir(temp_data_dir_path, temp_version_file_path):
|
def test_setup_data_dir(temp_data_dir_path, temp_version_file_path):
|
||||||
data_dir_path = temp_data_dir_path
|
data_dir_path = temp_data_dir_path
|
||||||
setup_data_dir(data_dir_path)
|
setup_data_dir(data_dir_path)
|
||||||
|
@ -41,8 +48,7 @@ def test_old_version_removed(monkeypatch, temp_data_dir_path, temp_version_file_
|
||||||
|
|
||||||
temp_data_dir_path.mkdir()
|
temp_data_dir_path.mkdir()
|
||||||
temp_version_file_path.write_text(old_version)
|
temp_version_file_path.write_text(old_version)
|
||||||
bogus_file_path = temp_data_dir_path / "test.txt"
|
bogus_file_path = create_bogus_file(temp_data_dir_path)
|
||||||
bogus_file_path.touch()
|
|
||||||
|
|
||||||
setup_data_dir(temp_data_dir_path)
|
setup_data_dir(temp_data_dir_path)
|
||||||
|
|
||||||
|
@ -58,8 +64,7 @@ def test_old_version_not_removed(
|
||||||
|
|
||||||
temp_data_dir_path.mkdir()
|
temp_data_dir_path.mkdir()
|
||||||
temp_version_file_path.write_text(old_version)
|
temp_version_file_path.write_text(old_version)
|
||||||
bogus_file_path = temp_data_dir_path / "test.txt"
|
bogus_file_path = create_bogus_file(temp_data_dir_path)
|
||||||
bogus_file_path.touch()
|
|
||||||
|
|
||||||
with pytest.raises(IncompatibleDataDirectory):
|
with pytest.raises(IncompatibleDataDirectory):
|
||||||
setup_data_dir(temp_data_dir_path)
|
setup_data_dir(temp_data_dir_path)
|
||||||
|
@ -71,8 +76,7 @@ def test_old_version_not_removed(
|
||||||
def test_data_dir_setup_not_needed(temp_data_dir_path, temp_version_file_path):
|
def test_data_dir_setup_not_needed(temp_data_dir_path, temp_version_file_path):
|
||||||
temp_data_dir_path.mkdir()
|
temp_data_dir_path.mkdir()
|
||||||
temp_version_file_path.write_text(current_version)
|
temp_version_file_path.write_text(current_version)
|
||||||
bogus_file_path = temp_data_dir_path / "test.txt"
|
bogus_file_path = create_bogus_file(temp_data_dir_path)
|
||||||
bogus_file_path.touch()
|
|
||||||
|
|
||||||
setup_data_dir(temp_data_dir_path)
|
setup_data_dir(temp_data_dir_path)
|
||||||
assert temp_version_file_path.read_text() == current_version
|
assert temp_version_file_path.read_text() == current_version
|
||||||
|
@ -84,3 +88,44 @@ def test_empty_data_dir(temp_data_dir_path, temp_version_file_path):
|
||||||
|
|
||||||
setup_data_dir(temp_data_dir_path)
|
setup_data_dir(temp_data_dir_path)
|
||||||
assert temp_version_file_path.read_text() == current_version
|
assert temp_version_file_path.read_text() == current_version
|
||||||
|
|
||||||
|
|
||||||
|
def test_new_data_dir_docker(monkeypatch, temp_data_dir_path, temp_version_file_path):
|
||||||
|
monkeypatch.setenv(DOCKER_ENV_VAR, "true")
|
||||||
|
|
||||||
|
temp_data_dir_path.mkdir()
|
||||||
|
bogus_file_path = create_bogus_file(temp_data_dir_path)
|
||||||
|
temp_version_file_path.write_text(current_version)
|
||||||
|
|
||||||
|
setup_data_dir(temp_data_dir_path)
|
||||||
|
assert temp_version_file_path.read_text() == current_version
|
||||||
|
assert bogus_file_path.is_file()
|
||||||
|
|
||||||
|
|
||||||
|
def test_data_dir_docker_old_version(monkeypatch, temp_data_dir_path, temp_version_file_path):
|
||||||
|
monkeypatch.setenv(DOCKER_ENV_VAR, "true")
|
||||||
|
|
||||||
|
temp_data_dir_path.mkdir()
|
||||||
|
temp_version_file_path.write_text(old_version)
|
||||||
|
|
||||||
|
with pytest.raises(IncompatibleDataDirectory):
|
||||||
|
setup_data_dir(temp_data_dir_path)
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_data_dir_docker(monkeypatch, temp_data_dir_path, temp_version_file_path):
|
||||||
|
monkeypatch.setenv(DOCKER_ENV_VAR, "true")
|
||||||
|
|
||||||
|
temp_data_dir_path.mkdir()
|
||||||
|
|
||||||
|
setup_data_dir(temp_data_dir_path)
|
||||||
|
assert temp_version_file_path.read_text() == current_version
|
||||||
|
|
||||||
|
|
||||||
|
def test_old_data_dir_docker_no_version(monkeypatch, temp_data_dir_path):
|
||||||
|
monkeypatch.setenv(DOCKER_ENV_VAR, "true")
|
||||||
|
|
||||||
|
temp_data_dir_path.mkdir()
|
||||||
|
create_bogus_file(temp_data_dir_path)
|
||||||
|
|
||||||
|
with pytest.raises(IncompatibleDataDirectory):
|
||||||
|
setup_data_dir(temp_data_dir_path)
|
||||||
|
|
Loading…
Reference in New Issue