|
6 | 6 |
|
7 | 7 | from deepdiff import DeepDiff
|
8 | 8 | from requests import HTTPError
|
9 |
| -from tenacity import retry |
10 |
| -from tenacity.retry import retry_if_result |
| 9 | +from tenacity import retry, wait_exponential |
| 10 | +from tenacity.retry import retry_if_exception_type, retry_if_result |
11 | 11 | from tenacity.stop import stop_after_attempt, stop_after_delay
|
12 | 12 | from tenacity.wait import wait_chain, wait_fixed
|
13 | 13 |
|
14 | 14 | from cloudpub.common import BaseService
|
15 |
| -from cloudpub.error import InvalidStateError, NotFoundError |
| 15 | +from cloudpub.error import ConflictError, InvalidStateError, NotFoundError, RunningSubmissionError |
16 | 16 | from cloudpub.models.ms_azure import (
|
17 | 17 | RESOURCE_MAPING,
|
18 | 18 | AzureResource,
|
|
38 | 38 | from cloudpub.ms_azure.session import PartnerPortalSession
|
39 | 39 | from cloudpub.ms_azure.utils import (
|
40 | 40 | AzurePublishingMetadata,
|
| 41 | + check_for_conflict, |
| 42 | + check_for_running_submission, |
41 | 43 | create_disk_version_from_scratch,
|
42 | 44 | is_azure_job_not_complete,
|
43 | 45 | is_sas_present,
|
@@ -175,6 +177,10 @@ def _wait_for_job_completion(self, job_id: str) -> ConfigureStatus:
|
175 | 177 | job_details = self._query_job_details(job_id=job_id)
|
176 | 178 | if job_details.job_result == "failed":
|
177 | 179 | error_message = f"Job {job_id} failed: \n{job_details.errors}"
|
| 180 | + if check_for_conflict(job_details): |
| 181 | + self._raise_error(ConflictError, error_message) |
| 182 | + elif check_for_running_submission(job_details): |
| 183 | + self._raise_error(RunningSubmissionError, error_message) |
178 | 184 | self._raise_error(InvalidStateError, error_message)
|
179 | 185 | elif job_details.job_result == "succeeded":
|
180 | 186 | log.debug(f"Job {job_id} succeeded")
|
@@ -548,7 +554,7 @@ def _publish_preview(self, product: Product, product_name: str) -> None:
|
548 | 554 | if res.job_result != 'succeeded' or not self.get_submission_state(
|
549 | 555 | product.id, state="preview"
|
550 | 556 | ):
|
551 |
| - errors = "\n".join(res.errors) |
| 557 | + errors = "\n".join(["%s: %s" % (error.code, error.message) for error in res.errors]) |
552 | 558 | failure_msg = (
|
553 | 559 | f"Failed to submit the product {product.id} to preview. "
|
554 | 560 | f"Status: {res.job_result} Errors: {errors}"
|
@@ -576,13 +582,19 @@ def _publish_live(self, product: Product, product_name: str) -> None:
|
576 | 582 | res = self.submit_to_status(product_id=product.id, status='live')
|
577 | 583 |
|
578 | 584 | if res.job_result != 'succeeded' or not self.get_submission_state(product.id, state="live"):
|
579 |
| - errors = "\n".join(res.errors) |
| 585 | + errors = "\n".join(["%s: %s" % (error.code, error.message) for error in res.errors]) |
580 | 586 | failure_msg = (
|
581 | 587 | f"Failed to submit the product {product.id} to live. "
|
582 | 588 | f"Status: {res.job_result} Errors: {errors}"
|
583 | 589 | )
|
584 | 590 | raise RuntimeError(failure_msg)
|
585 | 591 |
|
| 592 | + @retry( |
| 593 | + retry=retry_if_exception_type([ConflictError, RunningSubmissionError]), |
| 594 | + wait=wait_exponential(multiplier=1, min=60, max=60 * 60 * 24 * 7), |
| 595 | + stop=stop_after_attempt(3), |
| 596 | + reraise=True, |
| 597 | + ) |
586 | 598 | def publish(self, metadata: AzurePublishingMetadata) -> None:
|
587 | 599 | """
|
588 | 600 | Associate a VM image with a given product listing (destination) and publish it if required.
|
|
0 commit comments