Skip to content

Commit d04c185

Browse files
committed
Simplify: resolve authconfig once, pass it through directly
1 parent c1e5a9c commit d04c185

3 files changed

Lines changed: 22 additions & 42 deletions

File tree

src/context.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Dockerode from "dockerode";
44
import {getCurrent} from "./docker-api.js";
55
import {initHashedConfigs} from "./hashed-config.js";
66
import {ArgumentsCamelCase} from "yargs";
7-
import {loadDockerConfig} from "./docker-config.js";
7+
import {loadAuthConfig} from "./docker-config.js";
88

99

1010
export async function initContext (args: ArgumentsCamelCase) {
@@ -25,7 +25,7 @@ export async function initContext (args: ArgumentsCamelCase) {
2525

2626
const hashedConfigs = await initHashedConfigs(config);
2727

28-
const dockerConfig = await loadDockerConfig();
28+
const authconfig = await loadAuthConfig();
2929

30-
return {appName, config, dockerode, current, hashedConfigs, dockerConfig};
30+
return {appName, config, dockerode, current, hashedConfigs, authconfig};
3131
}

src/docker-api.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import Dockerode, {ConfigInfo, NetworkInspectInfo, Service} from "dockerode";
1+
import Dockerode, {AuthConfig, ConfigInfo, NetworkInspectInfo, Service} from "dockerode";
22
import {initServiceSpec, sortServiceSpec} from "./service-spec.js";
33
import {HashedConfigs} from "./hashed-config.js";
44
import {assertString} from "./asserts.js";
55
import {SwarmAppConfig} from "./swarm-app-config.js";
6-
import {DockerConfigFile, getAuthForImage} from "./docker-config.js";
76
import timers from "timers/promises";
87
import assert from "assert";
98

@@ -117,21 +116,19 @@ interface UpsertServicesOpts {
117116
current: DockerResources;
118117
appName: string;
119118
hashedConfigs: HashedConfigs;
120-
dockerConfig?: DockerConfigFile;
119+
authconfig?: AuthConfig | undefined;
121120
}
122-
export async function upsertServices ({dockerode, config, current, appName, hashedConfigs, dockerConfig}: UpsertServicesOpts) {
121+
export async function upsertServices ({dockerode, config, current, appName, hashedConfigs, authconfig}: UpsertServicesOpts) {
123122
for (const serviceName of Object.keys(config.service_specs)) {
124123
const serviceSpec = initServiceSpec({appName, serviceName, config, hashedConfigs, current});
125-
const image = config.service_specs[serviceName]?.image;
126-
const authconfig = image && dockerConfig ? getAuthForImage(image, dockerConfig) : undefined;
127124
const foundService = current.services.find((s) => s.Spec?.Name === `${appName}_${serviceName}`);
128125
if (!foundService) {
129126
console.log(`Creating service ${appName}_${serviceName}`);
130-
await dockerode.createService({...serviceSpec, authconfig});
127+
await dockerode.createService({...serviceSpec, authconfig: authconfig});
131128
} else {
132129
serviceSpec.version = foundService.Version?.Index ?? 0;
133130
console.log(`Updating service ${appName}_${serviceName}`);
134-
await dockerode.getService(foundService.ID).update({...serviceSpec, authconfig});
131+
await dockerode.getService(foundService.ID).update({...serviceSpec, authconfig: authconfig});
135132
}
136133
}
137134
}

src/docker-config.ts

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,30 @@ import fs from "fs";
22
import path from "path";
33
import {AuthConfig} from "dockerode";
44

5-
type DockerConfigAuths = Record<string, {auth?: string}>;
6-
7-
export interface DockerConfigFile {
8-
auths?: DockerConfigAuths;
9-
}
5+
export async function loadAuthConfig (): Promise<AuthConfig | undefined> {
6+
const configDir = process.env.DOCKER_CONFIG ?? path.join(process.env.HOME ?? "~", ".docker");
7+
const configPath = path.join(configDir, "config.json");
108

11-
function extractRegistry (image: string): string {
12-
const parts = image.split("/");
13-
const first = parts[0];
14-
if (parts.length >= 2 && first && (first.includes(".") || first.includes(":"))) {
15-
return first;
9+
let content: string;
10+
try {
11+
content = await fs.promises.readFile(configPath, "utf-8");
12+
} catch {
13+
return undefined;
1614
}
17-
return "https://index.docker.io/v1/";
18-
}
19-
20-
export function getAuthForImage (image: string, dockerConfig: DockerConfigFile): AuthConfig | undefined {
21-
if (!dockerConfig.auths) return undefined;
2215

23-
const registry = extractRegistry(image);
24-
const entry = dockerConfig.auths[registry];
25-
if (!entry?.auth) return undefined;
16+
const config = JSON.parse(content) as {auths?: Record<string, {auth?: string}>};
17+
const firstEntry = Object.entries(config.auths ?? {}).find(([, v]) => v.auth);
18+
if (!firstEntry) return undefined;
2619

20+
const [serveraddress, entry] = firstEntry;
21+
if (!entry.auth) return undefined;
2722
const decoded = Buffer.from(entry.auth, "base64").toString("utf-8");
2823
const separatorIndex = decoded.indexOf(":");
2924
if (separatorIndex === -1) return undefined;
3025

3126
return {
3227
username: decoded.substring(0, separatorIndex),
3328
password: decoded.substring(separatorIndex + 1),
34-
serveraddress: registry,
29+
serveraddress,
3530
};
3631
}
37-
38-
export async function loadDockerConfig (): Promise<DockerConfigFile> {
39-
const configDir = process.env.DOCKER_CONFIG ?? path.join(process.env.HOME ?? "~", ".docker");
40-
const configPath = path.join(configDir, "config.json");
41-
42-
try {
43-
const content = await fs.promises.readFile(configPath, "utf-8");
44-
return JSON.parse(content) as DockerConfigFile;
45-
} catch {
46-
return {};
47-
}
48-
}

0 commit comments

Comments
 (0)