abstract.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. """Abstract plugin class defining the interface needed to build container images for W&B Launch."""
  2. from __future__ import annotations
  3. from abc import ABC, abstractmethod
  4. from typing import TYPE_CHECKING, Any
  5. from wandb.sdk.launch.environment.abstract import AbstractEnvironment
  6. from wandb.sdk.launch.registry.abstract import AbstractRegistry
  7. from .._project_spec import EntryPoint, LaunchProject
  8. from ..registry.anon import AnonynmousRegistry
  9. from ..utils import (
  10. AZURE_CONTAINER_REGISTRY_URI_REGEX,
  11. ELASTIC_CONTAINER_REGISTRY_URI_REGEX,
  12. GCP_ARTIFACT_REGISTRY_URI_REGEX,
  13. )
  14. if TYPE_CHECKING:
  15. from wandb.sdk.launch.agent.job_status_tracker import JobAndRunStatusTracker
  16. class AbstractBuilder(ABC):
  17. """Abstract plugin class defining the interface needed to build container images for W&B Launch."""
  18. builder_type: str
  19. environment: AbstractEnvironment
  20. registry: AbstractRegistry
  21. builder_config: dict[str, Any]
  22. @abstractmethod
  23. def __init__(
  24. self,
  25. environment: AbstractEnvironment,
  26. registry: AbstractRegistry,
  27. verify: bool = True,
  28. ) -> None:
  29. """Initialize a builder.
  30. Arguments:
  31. builder_config: The builder config.
  32. registry: The registry to use.
  33. verify: Whether to verify the functionality of the builder.
  34. Raises:
  35. LaunchError: If the builder cannot be initialized or verified.
  36. """
  37. raise NotImplementedError
  38. @classmethod
  39. @abstractmethod
  40. def from_config(
  41. cls,
  42. config: dict,
  43. environment: AbstractEnvironment,
  44. registry: AbstractRegistry,
  45. ) -> AbstractBuilder:
  46. """Create a builder from a config dictionary.
  47. Arguments:
  48. config: The config dictionary.
  49. environment: The environment to use.
  50. registry: The registry to use.
  51. verify: Whether to verify the functionality of the builder.
  52. login: Whether to login to the registry immediately.
  53. Returns:
  54. The builder.
  55. """
  56. raise NotImplementedError
  57. @abstractmethod
  58. async def build_image(
  59. self,
  60. launch_project: LaunchProject,
  61. entrypoint: EntryPoint,
  62. job_tracker: JobAndRunStatusTracker | None = None,
  63. ) -> str:
  64. """Build the image for the given project.
  65. Arguments:
  66. launch_project: The project to build.
  67. build_ctx_path: The path to the build context.
  68. Returns:
  69. The image name.
  70. """
  71. raise NotImplementedError
  72. @abstractmethod
  73. async def verify(self) -> None:
  74. """Verify that the builder can be used to build images.
  75. Raises:
  76. LaunchError: If the builder cannot be used to build images.
  77. """
  78. raise NotImplementedError
  79. def registry_from_uri(uri: str) -> AbstractRegistry:
  80. """Create a registry helper object from a uri.
  81. This function parses the URI and determines which supported registry it
  82. belongs to. It then creates a registry helper object for that registry.
  83. The supported remote registry types are:
  84. - Azure Container Registry
  85. - Google Container Registry
  86. - AWS Elastic Container Registry
  87. The format of the URI is as follows:
  88. - Azure Container Registry: <registry-name>.azurecr.io/<repo-name>/<image-name>
  89. - Google Container Registry: <location>-docker.pkg.dev/<project-id>/<repo-name>/<image-name>
  90. - AWS Elastic Container Registry: <account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>/<image-name>
  91. Our classification of the registry is based on the domain name. For example,
  92. if the uri contains `.azurecr.io`, we classify it as an Azure
  93. Container Registry. If the uri contains `.dkr.ecr`, we classify
  94. it as an AWS Elastic Container Registry. If the uri contains
  95. `-docker.pkg.dev`, we classify it as a Google Artifact Registry.
  96. This function will attempt to load the appropriate cloud helpers for the
  97. `https://` prefix is optional for all of the above.
  98. Arguments:
  99. uri: The uri to create a registry from.
  100. Returns:
  101. The registry.
  102. Raises:
  103. LaunchError: If the registry helper cannot be loaded for the given URI.
  104. """
  105. if uri.startswith("https://"):
  106. uri = uri[len("https://") :]
  107. if AZURE_CONTAINER_REGISTRY_URI_REGEX.match(uri) is not None:
  108. from wandb.sdk.launch.registry.azure_container_registry import (
  109. AzureContainerRegistry,
  110. )
  111. return AzureContainerRegistry(uri=uri)
  112. elif GCP_ARTIFACT_REGISTRY_URI_REGEX.match(uri) is not None:
  113. from wandb.sdk.launch.registry.google_artifact_registry import (
  114. GoogleArtifactRegistry,
  115. )
  116. return GoogleArtifactRegistry(uri=uri)
  117. elif ELASTIC_CONTAINER_REGISTRY_URI_REGEX.match(uri) is not None:
  118. from wandb.sdk.launch.registry.elastic_container_registry import (
  119. ElasticContainerRegistry,
  120. )
  121. return ElasticContainerRegistry(uri=uri)
  122. return AnonynmousRegistry(uri=uri)