move global_common container logic to container.py

Container-specific methods in global_common class were basically
static methods. So it made sense to move these to container.py
This commit is contained in:
deeplow 2022-09-15 10:28:46 +01:00
parent 272281a29e
commit a822870853
No known key found for this signature in database
GPG key ID: 577982871529A52A
4 changed files with 98 additions and 93 deletions

View file

@ -7,6 +7,7 @@ from typing import Optional
import click import click
from colorama import Back, Fore, Style from colorama import Back, Fore, Style
from . import container
from .common import Common from .common import Common
from .container import convert from .container import convert
from .global_common import GlobalCommon from .global_common import GlobalCommon
@ -91,7 +92,7 @@ def cli_main(
exit(1) exit(1)
# Ensure container is installed # Ensure container is installed
global_common.install_container() container.install_container()
# Convert the document # Convert the document
print_header("Converting document to safe PDF") print_header("Converting document to safe PDF")

View file

@ -1,3 +1,4 @@
import gzip
import logging import logging
import os import os
import pipes import pipes
@ -9,7 +10,9 @@ from typing import Callable, List, Optional
import appdirs import appdirs
from .util import get_resource_path from .util import get_resource_path, get_subprocess_startupinfo
container_name = "dangerzone.rocks/dangerzone"
# What container tech is used for this platform? # What container tech is used for this platform?
if platform.system() == "Linux": if platform.system() == "Linux":
@ -31,6 +34,95 @@ log = logging.getLogger(__name__)
container_name = "dangerzone.rocks/dangerzone" container_name = "dangerzone.rocks/dangerzone"
def get_container_runtime() -> str:
if platform.system() == "Linux":
runtime_name = "podman"
else:
runtime_name = "docker"
runtime = shutil.which(runtime_name)
if runtime is None:
raise Exception(f"{runtime_name} is not installed")
return runtime
def install_container() -> Optional[bool]:
"""
Make sure the podman container is installed. Linux only.
"""
if is_container_installed():
return True
# Load the container into podman
log.info("Installing Dangerzone container image...")
p = subprocess.Popen(
[get_container_runtime(), "load"],
stdin=subprocess.PIPE,
startupinfo=get_subprocess_startupinfo(),
)
chunk_size = 10240
compressed_container_path = get_resource_path("container.tar.gz")
with gzip.open(compressed_container_path) as f:
while True:
chunk = f.read(chunk_size)
if len(chunk) > 0:
if p.stdin:
p.stdin.write(chunk)
else:
break
p.communicate()
if not is_container_installed():
log.error("Failed to install the container image")
return False
log.info("Container image installed")
return True
def is_container_installed() -> bool:
"""
See if the podman container is installed. Linux only.
"""
# Get the image id
with open(get_resource_path("image-id.txt")) as f:
expected_image_id = f.read().strip()
# See if this image is already installed
installed = False
found_image_id = subprocess.check_output(
[
get_container_runtime(),
"image",
"list",
"--format",
"{{.ID}}",
container_name,
],
text=True,
startupinfo=get_subprocess_startupinfo(),
)
found_image_id = found_image_id.strip()
if found_image_id == expected_image_id:
installed = True
elif found_image_id == "":
pass
else:
log.info("Deleting old dangerzone container image")
try:
subprocess.check_output(
[get_container_runtime(), "rmi", "--force", found_image_id],
startupinfo=get_subprocess_startupinfo(),
)
except:
log.warning("Couldn't delete old container image, so leaving it there")
return installed
def exec(args: List[str], stdout_callback: Callable[[str], None] = None) -> int: def exec(args: List[str], stdout_callback: Callable[[str], None] = None) -> int:
args_str = " ".join(pipes.quote(s) for s in args) args_str = " ".join(pipes.quote(s) for s in args)
log.info("> " + args_str) log.info("> " + args_str)

View file

@ -13,7 +13,7 @@ import colorama
from .container import convert from .container import convert
from .settings import Settings from .settings import Settings
from .util import get_resource_path, get_subprocess_startupinfo from .util import get_resource_path
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -30,98 +30,9 @@ class GlobalCommon(object):
# App data folder # App data folder
self.appdata_path = appdirs.user_config_dir("dangerzone") self.appdata_path = appdirs.user_config_dir("dangerzone")
# Container
self.container_name = "dangerzone.rocks/dangerzone"
# Languages supported by tesseract # Languages supported by tesseract
with open(get_resource_path("ocr-languages.json"), "r") as f: with open(get_resource_path("ocr-languages.json"), "r") as f:
self.ocr_languages = json.load(f) self.ocr_languages = json.load(f)
# Load settings # Load settings
self.settings = Settings(self) self.settings = Settings(self)
def get_container_runtime(self) -> str:
if platform.system() == "Linux":
runtime_name = "podman"
else:
runtime_name = "docker"
runtime = shutil.which(runtime_name)
if runtime is None:
raise Exception(f"{runtime_name} is not installed")
return runtime
def install_container(self) -> Optional[bool]:
"""
Make sure the podman container is installed. Linux only.
"""
if self.is_container_installed():
return True
# Load the container into podman
log.info("Installing Dangerzone container image...")
p = subprocess.Popen(
[self.get_container_runtime(), "load"],
stdin=subprocess.PIPE,
startupinfo=get_subprocess_startupinfo(),
)
chunk_size = 10240
compressed_container_path = get_resource_path("container.tar.gz")
with gzip.open(compressed_container_path) as f:
while True:
chunk = f.read(chunk_size)
if len(chunk) > 0:
if p.stdin:
p.stdin.write(chunk)
else:
break
p.communicate()
if not self.is_container_installed():
log.error("Failed to install the container image")
return False
log.info("Container image installed")
return True
def is_container_installed(self) -> bool:
"""
See if the podman container is installed. Linux only.
"""
# Get the image id
with open(get_resource_path("image-id.txt")) as f:
expected_image_id = f.read().strip()
# See if this image is already installed
installed = False
found_image_id = subprocess.check_output(
[
self.get_container_runtime(),
"image",
"list",
"--format",
"{{.ID}}",
self.container_name,
],
text=True,
startupinfo=get_subprocess_startupinfo(),
)
found_image_id = found_image_id.strip()
if found_image_id == expected_image_id:
installed = True
elif found_image_id == "":
pass
else:
log.info("Deleting old dangerzone container image")
try:
subprocess.check_output(
[self.get_container_runtime(), "rmi", "--force", found_image_id],
startupinfo=get_subprocess_startupinfo(),
)
except:
log.warning("Couldn't delete old container image, so leaving it there")
return installed

View file

@ -10,6 +10,7 @@ from typing import Optional
from colorama import Fore, Style from colorama import Fore, Style
from PySide2 import QtCore, QtGui, QtWidgets from PySide2 import QtCore, QtGui, QtWidgets
from .. import container
from ..common import Common from ..common import Common
from ..container import convert from ..container import convert
from ..global_common import GlobalCommon from ..global_common import GlobalCommon
@ -103,7 +104,7 @@ class InstallContainerThread(QtCore.QThread):
self.global_common = global_common self.global_common = global_common
def run(self) -> None: def run(self) -> None:
self.global_common.install_container() container.install_container()
self.finished.emit() self.finished.emit()