Source code for sirup.TemporaryFileWithRootPermission

import os
import subprocess
import tempfile


# adapted from https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file

[docs] class TemporaryFileWithRootPermission: """Temporary file that requires root permission. The purpose of this class is to handle files that the `OpenVPN` command-line interface (CLI) writes to. Because the CLI works with root permission, the files it writes to also require root permission, and can for instance only be removed with root permission. When used as a context manager, a random file name in a temporary directory is generated, which can then be used like normal file. Upon `__exit__`, the file is deleted. When used without a context manager, the `create_path` method needs to be called to generate the file name. The filename can be passed on to other tasks, like the openvpn subprocesses. To remove the file one needs to call `self.remove`. Args: passsword (str): Password for the user with root access. suffix (str, optional): suffix to be appended after the random file name. """ def __init__(self, password, suffix=None): self._pwd = password self._suffix = suffix
[docs] def __enter__(self): # Generate a random temporary file name file_name = os.path.join(tempfile.gettempdir(), os.urandom(8).hex()) if self._suffix is not None: file_name = file_name + self._suffix self.file_name = file_name return self.file_name
[docs] def create_path(self, file_name): """Create the full path to a new file in the temp directory. Remove any existing file with the same name. Args: file_name (str): name of the file in the temp directory. """ if self._suffix is not None: file_name = file_name + self._suffix self.file_name = os.path.join(tempfile.gettempdir(), file_name) if os.path.exists(self.file_name): self.remove()
[docs] def remove(self): "Remove the file." cmd = ["sudo", "-S", "rm", "-rf", self.file_name] subprocess.run(cmd, input=self._pwd.encode(), check=True)
[docs] def __exit__(self, exc_type, exc_val, exc_tb): if os.path.exists(self.file_name): with open(self.file_name, "rb"): # make sure file is closed properly pass cmd = ["sudo", "-S", "rm", "-rf", self.file_name] subprocess.run(cmd, input=self._pwd.encode(), check=True) assert not os.path.exists(self.file_name), "temporary file not deleted"