@@ -16,6 +16,7 @@ limitations under the License.
16
16
import fs from 'node:fs' ;
17
17
import os from 'node:os' ;
18
18
import path from 'node:path' ;
19
+ import { execFileSync } from 'node:child_process' ;
19
20
import { parseImageName } from './name' ;
20
21
21
22
export type Credentials = {
@@ -24,32 +25,21 @@ export type Credentials = {
24
25
} ;
25
26
26
27
type DockerConifg = {
27
- auths ?: { [ registry : string ] : { auth : string ; identitytoken ?: string } } ;
28
+ credsStore ?: string ,
29
+ auths ?: { [ registry : string ] : { auth : string ; identitytoken ?: string } } ,
30
+ credHelpers ?: { [ registry : string ] : string } ,
28
31
} ;
29
32
30
33
// Returns the credentials for a given registry by reading the Docker config
31
- // file.
32
- export const getRegistryCredentials = ( imageName : string ) : Credentials => {
33
- const { registry } = parseImageName ( imageName ) ;
34
- const dockerConfigFile = path . join ( os . homedir ( ) , '.docker' , 'config.json' ) ;
35
-
36
- let content : string | undefined ;
37
- try {
38
- content = fs . readFileSync ( dockerConfigFile , 'utf8' ) ;
39
- } catch ( err ) {
40
- throw new Error ( `No credential file found at ${ dockerConfigFile } ` ) ;
41
- }
42
-
43
- const dockerConfig : DockerConifg = JSON . parse ( content ) ;
44
-
34
+ function credentialFromAuths ( dockerConfig : DockerConifg , registry : string ) {
45
35
const credKey =
46
36
Object . keys ( dockerConfig ?. auths || { } ) . find ( ( key ) =>
47
37
key . includes ( registry )
48
38
) || registry ;
49
39
const creds = dockerConfig ?. auths ?. [ credKey ] ;
50
40
51
41
if ( ! creds ) {
52
- throw new Error ( `No credentials found for registry ${ registry } ` ) ;
42
+ return null ;
53
43
}
54
44
55
45
// Extract username/password from auth string
@@ -59,6 +49,74 @@ export const getRegistryCredentials = (imageName: string): Credentials => {
59
49
const pass = creds . identitytoken ? creds . identitytoken : password ;
60
50
61
51
return { username, password : pass } ;
52
+ }
53
+
54
+ function credentialFromCredHelpers ( dockerConfig : DockerConifg , registry : string ) {
55
+ // Check if the registry has a credHelper and use it if it does
56
+ const helper = dockerConfig ?. credHelpers ?. [ registry ] ;
57
+
58
+ if ( ! helper ) {
59
+ return null ;
60
+ }
61
+
62
+ return launchHelper ( helper , registry ) ;
63
+ }
64
+
65
+ function credentialFromCredsStore ( dockerConfig : DockerConifg , registry : string ) {
66
+ // If the credsStore is set, use it to get the credentials
67
+ const helper = dockerConfig ?. credsStore ;
68
+
69
+ if ( ! helper ) {
70
+ return null ;
71
+ }
72
+
73
+ return launchHelper ( helper , registry ) ;
74
+ }
75
+
76
+ function launchHelper ( helper : string , registry : string ) {
77
+ // Get the credentials from the helper.
78
+ // Parameter for helper is 'get' and registry is passed as input
79
+ // The helper should return a JSON object with the keys "Username" and "Secret"
80
+ try {
81
+ const output = execFileSync ( `docker-credential-${ helper } ` , [ "get" ] , {
82
+ input : registry ,
83
+ } ) . toString ( ) ;
84
+
85
+ const { Username : username , Secret : password } = JSON . parse ( output ) ;
86
+
87
+ return { username, password } ;
88
+ } catch ( err ) {
89
+ throw new Error ( `Failed to get credentials from helper ${ helper } for registry ${ registry } : ${ err } ` ) ;
90
+ }
91
+ }
92
+
93
+ // file.
94
+ export const getRegistryCredentials = ( imageName : string ) : Credentials => {
95
+ const { registry } = parseImageName ( imageName ) ;
96
+ const dockerConfigFile = path . join ( os . homedir ( ) , '.docker' , 'config.json' ) ;
97
+
98
+ let content : string | undefined ;
99
+ try {
100
+ content = fs . readFileSync ( dockerConfigFile , 'utf8' ) ;
101
+ } catch ( err ) {
102
+ throw new Error ( `No credential file found at ${ dockerConfigFile } ` ) ;
103
+ }
104
+
105
+ const dockerConfig : DockerConifg = JSON . parse ( content ) ;
106
+
107
+ const fromAuths = credentialFromAuths ( dockerConfig , registry ) ;
108
+ if ( fromAuths ) {
109
+ return fromAuths ;
110
+ }
111
+ const fromCredHelpers = credentialFromCredHelpers ( dockerConfig , registry ) ;
112
+ if ( fromCredHelpers ) {
113
+ return fromCredHelpers ;
114
+ }
115
+ const fromCredsStore = credentialFromCredsStore ( dockerConfig , registry ) ;
116
+ if ( fromCredsStore ) {
117
+ return fromCredsStore ;
118
+ }
119
+ throw new Error ( `No credentials found for registry ${ registry } ` ) ;
62
120
} ;
63
121
64
122
// Encode the username and password as base64-encoded basicauth value
0 commit comments