def __init__(self, **kwargs): """ Initializes the instance and checks that docker and vagrant are installed. """ super().__init__(**kwargs) try: import docker # noqa: F401 except ImportError: raise ArcaMisconfigured( ArcaMisconfigured.PACKAGE_MISSING.format("docker")) try: import vagrant except ImportError: raise ArcaMisconfigured( ArcaMisconfigured.PACKAGE_MISSING.format("python-vagrant")) try: import fabric # noqa: F401 except ImportError: raise ArcaMisconfigured( ArcaMisconfigured.PACKAGE_MISSING.format("fabric3")) if vagrant.get_vagrant_executable() is None: raise ArcaMisconfigured("Vagrant executable is not accessible!") self.vagrant: vagrant.Vagrant = None
def validate_configuration(self): """ Validates the provided settings. * Checks ``inherit_image`` format. * Checks ``use_registry_name`` format. * Checks that ``apt_dependencies`` is not set when ``inherit_image`` is set. :raise ArcaMisconfigured: If some of the settings aren't valid. """ super().validate_configuration() if self.inherit_image is not None: try: assert len(str(self.inherit_image).split(":")) == 2 except (ValueError, AssertionError): raise ArcaMisconfigured( f"Image '{self.inherit_image}' is not a valid value for the 'inherit_image'" f"setting") if self.inherit_image is not None and self.get_dependencies( ) is not None: raise ArcaMisconfigured( "An external image is used as a base image, " "therefore Arca can't install dependencies.") if self.use_registry_name is not None: try: assert 2 >= len(str(self.inherit_image).split("/")) <= 3 except ValueError: raise ArcaMisconfigured( f"Registry '{self.use_registry_name}' is not valid value for the " f"'use_registry_name' setting.")
def validate_configuration(self): """ Runs :meth:`arca.DockerBackend.validate_configuration` and checks extra: * ``box`` format * ``provider`` format * ``use_registry_name`` is set and ``registry_pull_only`` is not enabled. """ super().validate_configuration() if self.use_registry_name is None: raise ArcaMisconfigured("Use registry name setting is required for VagrantBackend") if not re.match(r"^[a-z]+/[a-zA-Z0-9\-_]+$", self.box): raise ArcaMisconfigured("Provided Vagrant box is not valid") if not re.match(r"^[a-z_]+$", self.provider): raise ArcaMisconfigured("Provided Vagrant provider is not valid") if self.registry_pull_only: raise ArcaMisconfigured("Push must be enabled for VagrantBackend")
def __init__(self, **kwargs): """ Initializes the instance and checks that the docker package is installed. """ super().__init__(**kwargs) if docker is None: raise ArcaMisconfigured( ArcaMisconfigured.PACKAGE_MISSING.format("docker")) self._containers = set() self.client = None self.alpine_inherited = None
def handle_requirements(self, repo: str, branch: str, repo_path: Path): """ Checks the differences and handles it using the selected strategy. """ if self.requirements_strategy == RequirementsStrategy.IGNORE: logger.info("Requirements strategy is IGNORE") return requirements = repo_path / self.requirements_location # explicitly configured there are no requirements for the current environment if self.current_environment_requirements is None: if not requirements.exists(): return # no diff, since no requirements both in current env and repository requirements_set = self.get_requirements_set(requirements) if len(requirements_set): if self.requirements_strategy == RequirementsStrategy.RAISE: raise RequirementsMismatch(f"There are extra requirements in repository {repo}, branch {branch}.", diff=requirements.read_text()) self.install_requirements(path=requirements) # requirements for current environment configured else: current_requirements = Path(self.current_environment_requirements) if not requirements.exists(): return # no req. file in repo -> no extra requirements logger.info("Searching for current requirements at absolute path %s", current_requirements) if not current_requirements.exists(): raise ArcaMisconfigured("Can't locate current environment requirements.") current_requirements_set = self.get_requirements_set(current_requirements) requirements_set = self.get_requirements_set(requirements) # only requirements that are extra in repository requirements matter extra_requirements_set = requirements_set - current_requirements_set if len(extra_requirements_set) == 0: return # no extra requirements in repository else: if self.requirements_strategy == RequirementsStrategy.RAISE: raise RequirementsMismatch(f"There are extra requirements in repository {repo}, branch {branch}.", diff="\n".join(extra_requirements_set)) elif self.requirements_strategy == RequirementsStrategy.INSTALL_EXTRA: self.install_requirements(requirements=extra_requirements_set)
def get_inherit_image(self) -> Tuple[str, str]: """ Parses the ``inherit_image`` setting, checks if the image is present locally and pulls it otherwise. :return: Returns the name and the tag of the image. :raise ArcaMisconfiguration: If the image can't be pulled from registries. """ name, tag = str(self.inherit_image).split(":") if self.image_exists(name, tag): return name, tag try: self.client.images.pull(name, tag) except docker.errors.APIError: raise ArcaMisconfigured( f"The specified image {self.inherit_image} from which Arca should inherit " f"can't be pulled") return name, tag
def get_dependencies(self) -> Optional[List[str]]: """ Returns the ``apt_dependencies`` setting to a standardized format. :raise ArcaMisconfigured: if the dependencies can't be converted into a list of strings :return: List of dependencies, ``None`` if there are none. """ if not self.apt_dependencies: return None try: dependencies = list( [str(x).strip() for x in self.apt_dependencies]) except (TypeError, ValueError): raise ArcaMisconfigured( "Apk dependencies can't be converted into a list of strings") if not len(dependencies): return None dependencies.sort() return dependencies