testcontainers / testcontainers/testcontainers-java

[Enhancement]: Lazy authentication in private registries before image pulling

Open
#8,004 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type/enhancement
Dominant language
Java
Stars
8.7k
Forks
1.9k
Avg merge
2d 17h
Merged PRs (30d)
9

Description

Module

Core

Proposal

Hello.

I keep my docker images in private Azure Container Registry (ACR). The registry requires Azure credentials to pull images. ACR works with JWT token which is valid up to 3 hours (doc). Azure recommends always log in to the registry before running a docker command with az acr login -n <registry_name>.

I've tried to implement such mechanism. Because each execution of command takes about 5-10 seconds it might be too expensive to login on each test run, especially when only one test is running and all required images already pulled. So the best option is to log into ACR lazily only if image hasn't been pulled yet. It could be checked via custom ImagePullPolicy wrapper (may be there are better ways to check..).

As far as I understand, TestContainers doesn't support this scenario. I suppose there should be option to customize RemoteDockerImage somehow to login into registry and reload cache in RegistryAuthLocator. Now once RegistryAuthLocator#cache is loaded it couldn't be reloaded natively via api.

I found a workaround and implemented AzureImagePullPolicyWrapper which implements ImagePullPolicy, but it uses reflection api to reload auth cache:

public class AzureImagePullPolicyWrapper implements ImagePullPolicy {
    // ...
    @Override
    public boolean shouldPull(DockerImageName imageName) {
        boolean shouldPull = delegate.shouldPull(imageName);
        if (!shouldPull) {
            return false;
        }

        var azureRegistryName = extractRegistryName(imageName.getRegistry());
        if (azureRegistryName.isEmpty()) {
            return true;
        }

        loginToAzureRegistry(azureRegistryName.get());
        resetRegistryAuthCache(imageName.getRegistry());
        return true;
    }
    // ..
    private void resetRegistryAuthCache(String registry) {
       try {
          Field cacheField = RegistryAuthLocator.class.getDeclaredField("cache");
          cacheField.setAccessible(true);
          var authLocator = RegistryAuthLocator.instance();
          Map<String, Optional<AuthConfig>> cache = (Map<String, Optional<AuthConfig>>) cacheField.get(authLocator);
          cache.remove(registry);
       } catch (NoSuchFieldException | IllegalAccessException e) {
          throw new RuntimeException(e);
       }
    }
}

Could I ask:

  1. Doesn't TestContainers support this scenario yet?
  2. Is it valid scenario to implement in library?

Thank you for your time :)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading RemoteDockerImage, ImagePullPolicy, and RegistryAuthLocator to understand when image pulling and authentication-cache lookup occur. Define what public customization or cache reload behavior is needed for lazy private-registry authentication, then verify the behavior with tests covering already-pulled and not-yet-pulled images.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, docker, java
Domain
cloud, devops, testing-qa
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.