Skip to content

Commit

Permalink
Fix Docker Hub paging and increase page size to 100 (#220)
Browse files Browse the repository at this point in the history
  • Loading branch information
bwateratmsft authored Jan 10, 2024
1 parent d848eff commit d56d5f2
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"files.insertFinalNewline": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
"source.fixAll": "explicit"
},
"git.branchProtection": [
"main",
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions packages/vscode-docker-registries/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## 0.1.11 - 10 January 2023
### Fixed
* Fixed an issue that prevented loading more than 10 repositories/tags from Docker Hub

## 0.1.10 - 5 December 2023
### Fixed
* Fixed a bug that prevented disconnecting from generic registries with certain special characters in the URL

## 0.1.9 - 5 December 2023
### Fixed
* Fixed Docker Hub sign in URL so that signing in from the CLI works more reliably

## 0.1.8 - 14 November 2023
### Fixed
* Uses Node.js 18 and removes the use of `node-fetch`

## 0.1.7 - 30 October 2023
### Fixed
* Fixed an infinite loop when getting a long list of repositories.
Expand Down
2 changes: 1 addition & 1 deletion packages/vscode-docker-registries/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@microsoft/vscode-docker-registries",
"author": "Microsoft Corporation",
"version": "0.1.10",
"version": "0.1.11",
"description": "Extensibility model for contributing registry providers to the Docker extension for Visual Studio Code",
"license": "See LICENSE in the project root for license information.",
"repository": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { DockerHubAuthProvider } from '../../auth/DockerHubAuthProvider';
import { BasicCredentials, LoginInformation } from '../../contracts/BasicCredentials';
import { isContextValueRegistryItem } from '../../contracts/RegistryItem';
import { getNextLinkFromHeaders, httpRequest } from '../../utils/httpRequest';
import { httpRequest } from '../../utils/httpRequest';
import { RegistryWizard } from '../../wizard/RegistryWizard';
import { RegistryWizardContext } from '../../wizard/RegistryWizardContext';
import { RegistryWizardRequiredUsernamePromptStep, RegistryWizardSecretPromptStep } from '../../wizard/RegistryWizardPromptStep';
Expand All @@ -28,6 +28,9 @@ export function isDockerHubRepository(item: unknown): item is CommonRepository {
return isRepository(item) && isContextValueRegistryItem(item) && item.additionalContextValues?.includes(DockerHubContextValue) === true;
}

// eslint-disable-next-line @typescript-eslint/naming-convention
const pageSizeQuery = new URLSearchParams({ page_size: '100' }).toString();

export class DockerHubRegistryDataProvider extends CommonRegistryDataProvider {
public readonly id = 'vscode-docker.dockerHub';
public readonly label = vscode.l10n.t('Docker Hub');
Expand Down Expand Up @@ -115,17 +118,20 @@ export class DockerHubRegistryDataProvider extends CommonRegistryDataProvider {
public async getRepositories(registry: CommonRegistry): Promise<CommonRepository[]> {
const results: CommonRepository[] = [];
let requestUrl: vscode.Uri | undefined = DockerHubRequestUrl
.with({ path: `v2/repositories/${registry.label}` });
.with({ path: `v2/repositories/${registry.label}` })
.with({ query: pageSizeQuery });

do {
const response = await httpRequest<{ results: [{ name: string; }] }>(requestUrl.toString(), {
const response = await httpRequest<{ next: string, results: [{ name: string; }] }>(requestUrl.toString(true), {
method: 'GET',
headers: {
Authorization: `Bearer ${(await this.authenticationProvider.getSession([], {})).accessToken}`,
}
});

for (const repository of (await response.json()).results) {
const jsonResult = await response.json();

for (const repository of jsonResult.results) {
results.push({
parent: registry,
label: `${repository.name}`,
Expand All @@ -134,7 +140,7 @@ export class DockerHubRegistryDataProvider extends CommonRegistryDataProvider {
});
}

requestUrl = getNextLinkFromHeaders(response.headers, registry.baseUrl);
requestUrl = getNextLinkFromBody(jsonResult);
} while (requestUrl);

return results;
Expand All @@ -143,18 +149,21 @@ export class DockerHubRegistryDataProvider extends CommonRegistryDataProvider {
public async getTags(repository: CommonRepository): Promise<CommonTag[]> {
const results: CommonTag[] = [];
let requestUrl: vscode.Uri | undefined = DockerHubRequestUrl
.with({ path: `v2/repositories/${repository.parent.label}/${repository.label}/tags` });
.with({ path: `v2/repositories/${repository.parent.label}/${repository.label}/tags` })
.with({ query: pageSizeQuery });

do {
// eslint-disable-next-line @typescript-eslint/naming-convention
const response = await httpRequest<{ results: [{ name: string, last_updated: string }] }>(requestUrl.toString(), {
const response = await httpRequest<{ next: string, results: [{ name: string, last_updated: string }] }>(requestUrl.toString(true), {
method: 'GET',
headers: {
Authorization: `Bearer ${(await this.authenticationProvider.getSession([], {})).accessToken}`,
}
});

for (const tag of (await response.json()).results) {
const jsonResult = await response.json();

for (const tag of jsonResult.results) {
results.push({
parent: repository,
label: tag.name,
Expand All @@ -164,7 +173,7 @@ export class DockerHubRegistryDataProvider extends CommonRegistryDataProvider {
});
}

requestUrl = getNextLinkFromHeaders(response.headers, repository.baseUrl);
requestUrl = getNextLinkFromBody(jsonResult);
} while (requestUrl);

return results;
Expand All @@ -175,30 +184,51 @@ export class DockerHubRegistryDataProvider extends CommonRegistryDataProvider {
}

private async getNamespaces(): Promise<string[]> {
const requestUrl = DockerHubRequestUrl
.with({ path: `v2/repositories/namespaces` });
const results: string[] = [];
let requestUrl: vscode.Uri | undefined = DockerHubRequestUrl
.with({ path: `v2/repositories/namespaces` })
.with({ query: pageSizeQuery });

const response = await httpRequest<{ namespaces: string[] }>(requestUrl.toString(), {
method: 'GET',
headers: {
Authorization: `Bearer ${(await this.authenticationProvider.getSession([], {})).accessToken}`,
}
});
do {
const response = await httpRequest<{ next: string, namespaces: string[] }>(requestUrl.toString(true), {
method: 'GET',
headers: {
Authorization: `Bearer ${(await this.authenticationProvider.getSession([], {})).accessToken}`,
}
});

const jsonResult = await response.json();

results.push(...jsonResult.namespaces || []);
requestUrl = getNextLinkFromBody(jsonResult);
} while (requestUrl);

return (await response.json()).namespaces || [];
return results;
}

private async getOrganizations(): Promise<string[]> {
const requestUrl = DockerHubRequestUrl
.with({ path: `v2/user/orgs` });
const results: string[] = [];
let requestUrl: vscode.Uri | undefined = DockerHubRequestUrl
.with({ path: `v2/user/orgs` })
.with({ query: pageSizeQuery });

const response = await httpRequest<{ results: [{ orgname: string }] }>(requestUrl.toString(), {
method: 'GET',
headers: {
Authorization: `Bearer ${(await this.authenticationProvider.getSession([], {})).accessToken}`,
}
});
do {
const response = await httpRequest<{ next: string, results: [{ orgname: string }] }>(requestUrl.toString(true), {
method: 'GET',
headers: {
Authorization: `Bearer ${(await this.authenticationProvider.getSession([], {})).accessToken}`,
}
});

const jsonResult = await response.json();
results.push(...jsonResult.results.map(org => org.orgname));
requestUrl = getNextLinkFromBody(jsonResult);
} while (requestUrl);

return (await response.json()).results.map(org => org.orgname) || [];
return results;
}
}

function getNextLinkFromBody(body: { next: string }): vscode.Uri | undefined {
return body.next ? vscode.Uri.parse(body.next) : undefined;
}

0 comments on commit d56d5f2

Please sign in to comment.