Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WX-1106 Add logging for failed docker manifest pulls #7135

Merged
merged 8 commits into from
May 18, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,15 @@ object DockerRegistryV2Abstract {
}

// Placeholder exceptions that can be carried through IO before being converted to a DockerInfoFailedResponse
private class Unauthorized() extends Exception
private class NotFound() extends Exception
private class Unauthorized(message: String, responseBody: String) extends Exception {
override def getMessage(): String = message + " " + responseBody
}
private class NotFound(message: String, responseBody: String) extends Exception {
override def getMessage(): String = message + " " + responseBody
}
private class UnknownError(message: String, responseBody: String) extends Exception {
override def getMessage(): String = message + " " + responseBody
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason you decided to do it this way rather than appending the body to the message the exception was created with? Is there a reason we need to maintain the status string as a separate message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So unfortunately, the override seems necessary to pipe the new arg to the message method. I did combine the inputs, and I do wonder if there is a better way to extend java exceptions, but I think this will have to do for now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might need:

private class Unauthorized(val message: String) extends Exception(message)

...but I also think it's fine as is for now.

}
}

/**
Expand Down Expand Up @@ -131,7 +138,10 @@ abstract class DockerRegistryV2Abstract(override val config: DockerRegistryConfi
protected def getDockerResponse(token: Option[String], dockerInfoContext: DockerInfoContext)(implicit client: Client[IO]): IO[DockerInfoSuccessResponse] = {
val requestDockerManifest = manifestRequest(token, dockerInfoContext.dockerImageID, AcceptDockerManifestV2Header)
lazy val requestOCIManifest = manifestRequest(token, dockerInfoContext.dockerImageID, AcceptOCIIndexV1Header)
def tryOCIManifest(err: Throwable) = executeRequest(requestOCIManifest, handleManifestResponse(dockerInfoContext, token))
def tryOCIManifest(err: Throwable) = {
logger.info(s"Manifest request failed for docker manifest V2, falling back to OCI manifest. Image: ${dockerInfoContext.dockerImageID}", err)
executeRequest(requestOCIManifest, handleManifestResponse(dockerInfoContext, token))
}
// Try to execute a request using the Docker Manifest format, and if that fails, try using the newer OCI manifest format
executeRequest(requestDockerManifest, handleManifestResponse(dockerInfoContext, token))
.handleErrorWith(tryOCIManifest)
Expand Down Expand Up @@ -282,9 +292,9 @@ abstract class DockerRegistryV2Abstract(override val config: DockerRegistryConfi

private def getDigestFromResponse(response: Response[IO]): IO[DockerHashResult] = response match {
case Status.Successful(r) => extractDigestFromHeaders(r.headers)
case Status.Unauthorized(_) => IO.raiseError(new Unauthorized)
case Status.NotFound(_) => IO.raiseError(new NotFound)
case failed => failed.as[String].flatMap(body => IO.raiseError(new Exception(s"Failed to get manifest: $body"))
case Status.Unauthorized(r) => r.as[String].flatMap(body => IO.raiseError(new Unauthorized(r.status.toString, body)))
case Status.NotFound(r) => r.as[String].flatMap(body => IO.raiseError(new NotFound(r.status.toString, body)))
case failed => failed.as[String].flatMap(body => IO.raiseError(new UnknownError(failed.status.toString, s"Failed to get manifest: $body"))
)
}

Expand Down