I'm trying to fetch a list of available images and their tags from Google Container Registry (gcr.io) in Node.js.
I first use google-auto-auth
to optain a token with scope https://www.googleapis.com/auth/devstorage.read_write
,
and I exchange that token for a gcr.io
token like so:
axios.get('https://gcr.io/v2/token?service=gcr.io', {
auth: {
username: '_token',
password: token // token I got from `google-auto-auth`
}
})
I then try to use this to call the v2/_catalog
endpoint:
axios.get('https://gcr.io/v2/_catalog', {
headers: {
Authorization: `Bearer ${gcrToken}`
}
})
And I get the following error:
{
errors: [ { code: 'DENIED', message: 'Failed to retrieve projects.' } ]
}
Fair enough, it must require my project ID, but where am I supposed to provide it?
Just to see if I could get anything else working, I tried:
axios.get('https://gcr.io/v2/my-project-id/my-image/tags/list', {
headers: {
Authorization: `Bearer ${gcrToken}`
}
})
And I get the following back:
{
errors: [
{
code: 'NAME_INVALID',
message: 'Requested repository does not match bearer token resource: my-project-id/my-image'
}
]
}
How can I read image info from gcr.io?
After extensive communication with Jon Johnson from GCR, we finally figured out what was wrong. If you upvote this answer, please upvote Jon's as well, he went above and beyond to get this issue resolved.
Most of this stuff is undocumented as of this writing.
registry:catalog:*
scope.us.gcr.io
, and they treat them as separate registries — I thought they were mirrors.Project Viewer
role in Google Cloud IAM.Basic base64(_token:<token>)
, the Google Cloud token can.Getting the GCR token
// Updated host
axios.get('https://us.gcr.io/v2/token?service=gcr.io', {
params: {
service: 'us.gcr.io',
scope: `registry:catalog:*`
},
auth: {
username: '_token',
password: token // token I got from `google-auto-auth`
},
})
Using the token to list repositories
const client = axios.create({
baseURL: `https://us.gcr.io/v2`,
headers: {
Authorization: `Bearer ${token}`
}
})
client.get('/_catalog').then((response) => {
console.log(response.data.repositories)
})