如何在(私有)Docker注册表(API v2)中查找映像的创建日期?

如何在(私有)Docker注册表(API v2)中查找映像的创建日期?,docker,docker-registry,Docker,Docker Registry,我想使用v2 API在私有Docker注册表中查找图像的最新时间戳,而无需先将图像拉到本地主机。因此,经过一些黑客攻击,我使用curl和jq工具完成了以下工作: curl -X GET http://registry:5000/v2/<IMAGE>/manifests/<TAG> \ | jq -r '.history[].v1Compatibility' \ | jq '.created' \ | sort \ | tail -n1 c

我想使用v2 API在私有Docker注册表中查找图像的最新时间戳,而无需先将图像拉到本地主机。

因此,经过一些黑客攻击,我使用
curl
jq
工具完成了以下工作:

curl -X GET http://registry:5000/v2/<IMAGE>/manifests/<TAG> \
    | jq -r '.history[].v1Compatibility' \
    | jq '.created' \
    | sort \
    | tail -n1
curl-X GEThttp://registry:5000/v2//manifests/ \
|jq-r'.历史记录[].v1兼容性'\
|jq'.已创建'\
|分类\
|尾部-n1
这似乎是可行的,但我真的不知道如何解释v1兼容性表示,所以我不知道我是否真的从中得到了正确的数字


欢迎对此发表评论

对@snth答案的一个小改进:使用
date
,打印日期更方便用户:

date --date=$(curl -s -X GET http://$REGISTRY:5000/v2/$IMAGE/manifests/$TAG | \
  jq -r '.history[].v1Compatibility' | jq -r '.created' | sort | tail -n 1 )
打印如下内容:

Fr 12. Okt 15:26:03 CEST 2018
在这里编译上面的评论和答案是一个完整的解决方案

通过身份验证
#设置变量使其更实用
用户名=docker\u用户
密码=docker\u通行证
DOCKER_注册表=http://my-registry.myorg.org:9080
回购=我的回购
TAG=atag
#查询注册表并将结果传送到jq
DOCKER_DATE=$(curl-s-u$用户名:$PASSWORD-H'Accept:application/vnd.DOCKER.distribution.manifest.v1+json'-X GET http://$REGISTRY_URL/v2/circle lb/manifests/master | jq-r'[.history[]]| map(.v1兼容性| fromjson |已创建)|排序|反向|[0])
echo“日期为$REPO:$TAG为$DOCKER\u日期”
未经认证 最后,如果要使用date命令(gnudate)进行解析

在linux上:

date -d $DOCKER_DATE
在mac上:

gdate -d $DOCKER_DATE
以下是dotnet core(C#)的实现,以防有人感兴趣:

    public class DockerHub{
    public DockerRegistryToken GetRegistryToken(string image){
        Console.WriteLine("authenticateing with dockerhub");
        using HttpClient client = new ();   
        var url = string.Format($"https://auth.docker.io/token?service=registry.docker.io&scope=repository:{image}:pull");
        //var response = client.Send(new HttpRequestMessage(HttpMethod.Get, url));
        var result = client.GetStringAsync(url);            
        var drt = JsonSerializer.Deserialize<DockerRegistryToken>(result.Result);        
        return drt;
    }

    public DateTime GetRemoteImageDate(string image, string tag, DockerRegistryToken token){

        using HttpClient client = new ();           
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.docker.distribution.manifest.list.v2+json"));
        
    
        var manifestResult = client.GetStringAsync(string.Format($"https://registry-1.docker.io/v2/{image}/manifests/{tag}"));  
        var json = JsonDocument.Parse(manifestResult.Result);

        var created = json.RootElement.GetProperty("history").EnumerateArray()
                    .Select(m => JsonDocument.Parse(m.GetProperty("v1Compatibility").ToString()).RootElement.GetProperty("created"))
                    .Select(m => DateTime.Parse(m.GetString()))
                    .OrderByDescending(m => m)
                    .FirstOrDefault(); // I challange you to improve this
        Console.WriteLine("Date recieved: {0}",created);
        return created.ToUniversalTime();

    }   
}

public class DockerRegistryToken{
    [JsonPropertyName("token")]
    public string Token { get; set; }

    /// always null
    [JsonPropertyName("access_token")]
    public string AccessToken  {get; set; }

    [JsonPropertyName("expires_in")]
    public int ExpiresInSeconds { get; set; }

    [JsonPropertyName("issued_at")]
    public DateTime IssuedAt { get; set; }

}

你必须接受你的答案,我今天在谷歌上搜索了一整天,没有找到更好的方法:(谢谢comemnt@griefThank!作为了解更多jq的借口,我将解析浓缩成一个命令:
jq-r'[.history[]| map(.v1Compatibility | fromjson |.created)| sort |[0]
Oops,忘记了相反的命令:
jq-r'[.history[.history[]|map(.v1兼容性| fromjson |.created)排序|反向|[0]
对此做一些检查,不总是“历史”中的第一个对象最新的一个吗?我使用
jq-r'[.history[0]]得到相同的结果。map(.v1兼容性| fromjson |.created)
谢谢,日期有帮助!让其他人的生活更轻松一点-在$(…),它类似于接受答案中的命令,但“jq-r”。创建的“bit”具有“-r”标志
    public class DockerHub{
    public DockerRegistryToken GetRegistryToken(string image){
        Console.WriteLine("authenticateing with dockerhub");
        using HttpClient client = new ();   
        var url = string.Format($"https://auth.docker.io/token?service=registry.docker.io&scope=repository:{image}:pull");
        //var response = client.Send(new HttpRequestMessage(HttpMethod.Get, url));
        var result = client.GetStringAsync(url);            
        var drt = JsonSerializer.Deserialize<DockerRegistryToken>(result.Result);        
        return drt;
    }

    public DateTime GetRemoteImageDate(string image, string tag, DockerRegistryToken token){

        using HttpClient client = new ();           
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.docker.distribution.manifest.list.v2+json"));
        
    
        var manifestResult = client.GetStringAsync(string.Format($"https://registry-1.docker.io/v2/{image}/manifests/{tag}"));  
        var json = JsonDocument.Parse(manifestResult.Result);

        var created = json.RootElement.GetProperty("history").EnumerateArray()
                    .Select(m => JsonDocument.Parse(m.GetProperty("v1Compatibility").ToString()).RootElement.GetProperty("created"))
                    .Select(m => DateTime.Parse(m.GetString()))
                    .OrderByDescending(m => m)
                    .FirstOrDefault(); // I challange you to improve this
        Console.WriteLine("Date recieved: {0}",created);
        return created.ToUniversalTime();

    }   
}

public class DockerRegistryToken{
    [JsonPropertyName("token")]
    public string Token { get; set; }

    /// always null
    [JsonPropertyName("access_token")]
    public string AccessToken  {get; set; }

    [JsonPropertyName("expires_in")]
    public int ExpiresInSeconds { get; set; }

    [JsonPropertyName("issued_at")]
    public DateTime IssuedAt { get; set; }

}
        var client = new DockerHub();
        var tok = client.GetRegistryToken("your/reponame");
        var remoteImageDate = client.GetRemoteImageDate("your/reponame","latest",tok);