Repository: GoogleContainerTools/jib
File: jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java (Java)

Code before:
      throws LayerCountMismatchException, BadContainerConfigurationFormatException {
    EventHandlers eventHandlers = buildContext.getEventHandlers();

    Collection<Map.Entry<String, String>> mirrorEntries =
        buildContext.getRegistryMirrors().entries();
    try (ProgressEventDispatcher progressDispatcher1 =
            progressDispatcherFactory.create("trying mirrors", mirrorEntries.size());
        TimerEventDispatcher ignored1 = new TimerEventDispatcher(eventHandlers, "trying mirrors")) {
      for (Map.Entry<String, String> entry : mirrorEntries) {
        String registry = entry.getKey();
        String mirror = entry.getValue();
        eventHandlers.dispatch(LogEvent.debug("mirror config: " + registry + " --> " + mirror));

        if (!buildContext.getBaseImageConfiguration().getImageRegistry().equals(registry)) {
          progressDispatcher1.dispatchProgress(1);
          continue;
        }

        eventHandlers.dispatch(LogEvent.info("trying mirror " + mirror + " for the base image"));
        try (ProgressEventDispatcher progressDispatcher2 =
            progressDispatcher1.newChildProducer().create("trying mirror " + mirror, 2)) {
          // First, try with no credentials. This works with public GCR images.
          RegistryClient registryClient =
              buildContext.newBaseImageRegistryClientFactory(mirror).newRegistryClient();
          return getImagesAndRegistryClient(
              eventHandlers, mirror, progressDispatcher2, registryClient);

        } catch (IOException | RegistryException ex) {
          // Ignore errors from this mirror and continue.
          eventHandlers.dispatch(
              LogEvent.debug(
                  "failed to get manifest from mirror " + mirror + ": " + ex.getMessage()));
        }
      }
      return Optional.empty();
    }
  }

  private Optional<ImagesAndRegistryClient> getImagesAndRegistryClient(
      EventHandlers eventHandlers,
      String mirror,
      ProgressEventDispatcher progressDispatcher2,
      RegistryClient registryClient)
      throws IOException, RegistryException, LayerCountMismatchException,
          BadContainerConfigurationFormatException {
    try {
      List<Image> images = pullBaseImages(registryClient, progressDispatcher2.newChildProducer());
      eventHandlers.dispatch(LogEvent.info("pulled manifest from mirror " + mirror));
      return Optional.of(new ImagesAndRegistryClient(images, registryClient));

    } catch (RegistryUnauthorizedException ex) {

Review comment (suggestion):
```suggestion
          List<Image> images = pullPublicImages(eventHandlers, registryClient, progressDispatcher2);
          eventHandlers.dispatch(LogEvent.info("pulled manifest from mirror " + mirror));
          return Optional.of(new ImagesAndRegistryClient(images, registryClient));
```

Code after:
      throws LayerCountMismatchException, BadContainerConfigurationFormatException {
    EventHandlers eventHandlers = buildContext.getEventHandlers();

    Collection<Map.Entry<String, String>> mirrorEntries =
        buildContext.getRegistryMirrors().entries();
    try (ProgressEventDispatcher progressDispatcher1 =
            progressDispatcherFactory.create("trying mirrors", mirrorEntries.size());
        TimerEventDispatcher ignored1 = new TimerEventDispatcher(eventHandlers, "trying mirrors")) {
      for (Map.Entry<String, String> entry : mirrorEntries) {
        String registry = entry.getKey();
        String mirror = entry.getValue();
        eventHandlers.dispatch(LogEvent.debug("mirror config: " + registry + " --> " + mirror));

        if (!buildContext.getBaseImageConfiguration().getImageRegistry().equals(registry)) {
          progressDispatcher1.dispatchProgress(1);
          continue;
        }

        eventHandlers.dispatch(LogEvent.info("trying mirror " + mirror + " for the base image"));
        try (ProgressEventDispatcher progressDispatcher2 =
            progressDispatcher1.newChildProducer().create("trying mirror " + mirror, 2)) {
          RegistryClient registryClient =
              buildContext.newBaseImageRegistryClientFactory(mirror).newRegistryClient();
          List<Image> images = pullPublicImages(eventHandlers, registryClient, progressDispatcher2);
          eventHandlers.dispatch(LogEvent.info("pulled manifest from mirror " + mirror));
          return Optional.of(new ImagesAndRegistryClient(images, registryClient));

        } catch (IOException | RegistryException ex) {
          // Ignore errors from this mirror and continue.
          eventHandlers.dispatch(
              LogEvent.debug(
                  "failed to get manifest from mirror " + mirror + ": " + ex.getMessage()));
        }
      }
      return Optional.empty();
    }
  }

  private List<Image> pullPublicImages(
      EventHandlers eventHandlers,
      RegistryClient registryClient,
      ProgressEventDispatcher progressDispatcher)
      throws IOException, RegistryException, LayerCountMismatchException,
          BadContainerConfigurationFormatException {
    try {
      // First, try with no credentials. This works with public GCR images.
      return pullBaseImages(registryClient, progressDispatcher.newChildProducer());

    } catch (RegistryUnauthorizedException ex) {
      // in case if a registry requires bearer auth
      registryClient.doPullBearerAuth();