fix digest count (#2674)

* fix digest count
* fix digest count
* fix digest count
* Merge branch 'main' of https://git0.harness.io/l7B_kbSEQD2wjrM7PShm5w/PROD/Harness_Commons/gitness into AH-293-fix
* fix digest count
CODE-2402
Pragyesh Mishra 2024-09-09 12:55:44 +00:00 committed by Harness
parent 644678f50c
commit 010e584b3f
7 changed files with 115 additions and 50 deletions

View File

@ -73,10 +73,10 @@ func GetTagMetadata(
registryURL string, registryURL string,
) []artifactapi.ArtifactVersionMetadata { ) []artifactapi.ArtifactVersionMetadata {
artifactVersionMetadataList := []artifactapi.ArtifactVersionMetadata{} artifactVersionMetadataList := []artifactapi.ArtifactVersionMetadata{}
digestCount := int64(1)
for _, tag := range *tags { for _, tag := range *tags {
modifiedAt := GetTimeInMs(tag.ModifiedAt) modifiedAt := GetTimeInMs(tag.ModifiedAt)
size := GetImageSize(tag.Size) size := GetImageSize(tag.Size)
digestCount := tag.DigestCount
isLatestVersion := latestTag == tag.Name isLatestVersion := latestTag == tag.Name
command := GetPullCommand(rootIdentifier, regIdentifier, image, tag.Name, string(tag.PackageType), registryURL) command := GetPullCommand(rootIdentifier, regIdentifier, image, tag.Name, string(tag.PackageType), registryURL)
packageType, err := toPackageType(string(tag.PackageType)) packageType, err := toPackageType(string(tag.PackageType))

View File

@ -16,12 +16,20 @@ package metadata
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
apiauth "github.com/harness/gitness/app/api/auth" apiauth "github.com/harness/gitness/app/api/auth"
"github.com/harness/gitness/app/api/request" "github.com/harness/gitness/app/api/request"
"github.com/harness/gitness/registry/app/api/openapi/contracts/artifact" "github.com/harness/gitness/registry/app/api/openapi/contracts/artifact"
ml "github.com/harness/gitness/registry/app/manifest/manifestlist"
os "github.com/harness/gitness/registry/app/manifest/ocischema"
s2 "github.com/harness/gitness/registry/app/manifest/schema2"
"github.com/harness/gitness/registry/app/pkg/docker"
"github.com/harness/gitness/registry/types"
"github.com/harness/gitness/types/enum" "github.com/harness/gitness/types/enum"
"github.com/rs/zerolog/log"
) )
func (c *APIController) GetAllArtifactVersions( func (c *APIController) GetAllArtifactVersions(
@ -73,11 +81,11 @@ func (c *APIController) GetAllArtifactVersions(
) )
if err != nil { if err != nil {
return artifact.GetAllArtifactVersions500JSONResponse{ return throw500Error(err)
InternalServerErrorJSONResponse: artifact.InternalServerErrorJSONResponse( }
*GetErrorResponse(http.StatusInternalServerError, err.Error()), err = setDigestCount(ctx, *tags)
), if err != nil {
}, nil return throw500Error(err)
} }
return artifact.GetAllArtifactVersions200JSONResponse{ return artifact.GetAllArtifactVersions200JSONResponse{
@ -87,3 +95,46 @@ func (c *APIController) GetAllArtifactVersions(
), ),
}, nil }, nil
} }
func setDigestCount(ctx context.Context, tags []types.TagMetadata) error {
for i := range tags {
err := setDigestCountInTagMetadata(ctx, &tags[i])
if err != nil {
return err
}
}
return nil
}
func setDigestCountInTagMetadata(ctx context.Context, t *types.TagMetadata) error {
m := types.Manifest{
SchemaVersion: t.SchemaVersion,
MediaType: t.MediaType,
NonConformant: t.NonConformant,
Payload: t.Payload,
}
manifest, err := docker.DBManifestToManifest(&m)
if err != nil {
log.Ctx(ctx).Error().Stack().Err(err).Msg("Failed to convert DBManifest to Manifest")
return err
}
switch reqManifest := manifest.(type) {
case *s2.DeserializedManifest, *os.DeserializedManifest:
t.DigestCount = 1
case *ml.DeserializedManifestList:
t.DigestCount = len(reqManifest.Manifests)
default:
err = fmt.Errorf("unknown manifest type: %T", manifest)
log.Ctx(ctx).Error().Stack().Err(err).Msg("Failed to set digest count")
}
return nil
}
func throw500Error(err error) (artifact.GetAllArtifactVersionsResponseObject, error) {
wrappedErr := fmt.Errorf("internal server error: %w", err)
return artifact.GetAllArtifactVersions500JSONResponse{
InternalServerErrorJSONResponse: artifact.InternalServerErrorJSONResponse(
*GetErrorResponse(http.StatusInternalServerError, wrappedErr.Error()),
),
}, nil
}

View File

@ -1070,7 +1070,6 @@ components:
type: string type: string
digestCount: digestCount:
type: integer type: integer
format: int64
pullCommand: pullCommand:
type: string type: string
downloadsCount: downloadsCount:

View File

@ -3704,47 +3704,47 @@ var swaggerSpec = []string{
"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",
"5dfl/wIAAP//tvNQvIqOAAA=", "y6/L/wUAAP//B0v/XHmOAAA=",
} }
// GetSwagger returns the content of the embedded swagger specification file // GetSwagger returns the content of the embedded swagger specification file

View File

@ -106,7 +106,7 @@ type ArtifactSummary struct {
// ArtifactVersionMetadata Artifact Version Metadata // ArtifactVersionMetadata Artifact Version Metadata
type ArtifactVersionMetadata struct { type ArtifactVersionMetadata struct {
DigestCount *int64 `json:"digestCount,omitempty"` DigestCount *int `json:"digestCount,omitempty"`
DownloadsCount *int64 `json:"downloadsCount,omitempty"` DownloadsCount *int64 `json:"downloadsCount,omitempty"`
IslatestVersion *bool `json:"islatestVersion,omitempty"` IslatestVersion *bool `json:"islatestVersion,omitempty"`
LastModified *string `json:"lastModified,omitempty"` LastModified *string `json:"lastModified,omitempty"`

View File

@ -86,6 +86,10 @@ type tagMetadataDB struct {
DigestCount int `db:"digest_count"` DigestCount int `db:"digest_count"`
IsLatestVersion bool `db:"latest_version"` IsLatestVersion bool `db:"latest_version"`
ModifiedAt int64 `db:"modified_at"` ModifiedAt int64 `db:"modified_at"`
SchemaVersion int `db:"manifest_schema_version"`
NonConformant bool `db:"manifest_non_conformant"`
Payload []byte `db:"manifest_payload"`
MediaType string `db:"mt_media_type"`
} }
type tagDetailDB struct { type tagDetailDB struct {
@ -717,11 +721,14 @@ func (t tagDao) GetAllTagsByRepoAndImage(
) (*[]types.TagMetadata, error) { ) (*[]types.TagMetadata, error) {
q := databaseg.Builder.Select( q := databaseg.Builder.Select(
"t.tag_name as name, m.manifest_total_size as size,"+ "t.tag_name as name, m.manifest_total_size as size,"+
" r.registry_package_type as package_type, t.tag_updated_at as modified_at", " r.registry_package_type as package_type, t.tag_updated_at as modified_at, "+
" m.manifest_schema_version, m.manifest_non_conformant, m.manifest_payload, "+
" mt.mt_media_type ",
). ).
From("tags t"). From("tags t").
Join("registries r ON t.tag_registry_id = r.registry_id"). Join("registries r ON t.tag_registry_id = r.registry_id").
Join("manifests m ON t.tag_manifest_id = m.manifest_id"). Join("manifests m ON t.tag_manifest_id = m.manifest_id").
Join("media_types mt ON mt.mt_id = m.manifest_media_type_id").
Where( Where(
"r.registry_parent_id = ? AND r.registry_name = ? AND t.tag_image_name = ?", "r.registry_parent_id = ? AND r.registry_name = ? AND t.tag_image_name = ?",
parentID, repoKey, image, parentID, repoKey, image,
@ -919,6 +926,10 @@ func (t tagDao) mapToTagMetadata(
DigestCount: dst.DigestCount, DigestCount: dst.DigestCount,
IsLatestVersion: dst.IsLatestVersion, IsLatestVersion: dst.IsLatestVersion,
ModifiedAt: time.UnixMilli(dst.ModifiedAt), ModifiedAt: time.UnixMilli(dst.ModifiedAt),
SchemaVersion: dst.SchemaVersion,
NonConformant: dst.NonConformant,
MediaType: dst.MediaType,
Payload: dst.Payload,
}, nil }, nil
} }

View File

@ -51,6 +51,10 @@ type TagMetadata struct {
DigestCount int DigestCount int
IsLatestVersion bool IsLatestVersion bool
ModifiedAt time.Time ModifiedAt time.Time
SchemaVersion int
NonConformant bool
Payload Payload
MediaType string
} }
type TagDetail struct { type TagDetail struct {