Skip to content

Commit

Permalink
feat: implement the AI model processor
Browse files Browse the repository at this point in the history
Signed-off-by: chlins <chlins.zhang@gmail.com>
  • Loading branch information
chlins committed Feb 26, 2025
1 parent add0b60 commit 162737a
Show file tree
Hide file tree
Showing 22 changed files with 1,859 additions and 11 deletions.
17 changes: 12 additions & 5 deletions api/v2.0/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1449,7 +1449,14 @@ paths:
in: path
description: The type of addition.
type: string
enum: [build_history, values.yaml, readme.md, dependencies, sbom]
enum:
- build_history
- values.yaml
- readme.md
- dependencies
- sbom
- license
- files
required: true
responses:
'200':
Expand Down Expand Up @@ -1795,7 +1802,7 @@ paths:
items:
$ref: '#/definitions/AuditLogEventType'
'401':
$ref: '#/responses/401'
$ref: '#/responses/401'
/projects/{project_name}/logs:
get:
summary: Get recent logs of the projects (deprecated)
Expand Down Expand Up @@ -1863,7 +1870,7 @@ paths:
'401':
$ref: '#/responses/401'
'500':
$ref: '#/responses/500'
$ref: '#/responses/500'
/p2p/preheat/providers:
get:
summary: List P2P providers
Expand Down Expand Up @@ -6949,8 +6956,8 @@ definitions:
description: The time when this operation is triggered.
AuditLogEventType:
type: object
properties:
event_type:
properties:
event_type:
type: string
description: the event type, such as create_user.
example: create_user
Expand Down
Binary file added icons/model.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/controller/artifact/abstractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (a *abstractor) AbstractMetadata(ctx context.Context, artifact *artifact.Ar
default:
return fmt.Errorf("unsupported manifest media type: %s", artifact.ManifestMediaType)
}
return processor.Get(artifact.MediaType).AbstractMetadata(ctx, artifact, content)
return processor.Get(artifact.ResolveArtifactType()).AbstractMetadata(ctx, artifact, content)
}

// the artifact is enveloped by docker manifest v1
Expand Down
12 changes: 7 additions & 5 deletions src/controller/artifact/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/goharbor/harbor/src/controller/artifact/processor/chart"
"github.com/goharbor/harbor/src/controller/artifact/processor/cnab"
"github.com/goharbor/harbor/src/controller/artifact/processor/image"
"github.com/goharbor/harbor/src/controller/artifact/processor/model"
"github.com/goharbor/harbor/src/controller/artifact/processor/sbom"
"github.com/goharbor/harbor/src/controller/artifact/processor/wasm"
"github.com/goharbor/harbor/src/controller/event/metadata"
Expand All @@ -44,7 +45,7 @@ import (
accessorymodel "github.com/goharbor/harbor/src/pkg/accessory/model"
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/artifactrash"
"github.com/goharbor/harbor/src/pkg/artifactrash/model"
trashmodel "github.com/goharbor/harbor/src/pkg/artifactrash/model"
"github.com/goharbor/harbor/src/pkg/blob"
"github.com/goharbor/harbor/src/pkg/immutable/match"
"github.com/goharbor/harbor/src/pkg/immutable/match/rule"
Expand Down Expand Up @@ -78,6 +79,7 @@ var (
cnab.ArtifactTypeCNAB: icon.DigestOfIconCNAB,
wasm.ArtifactTypeWASM: icon.DigestOfIconWASM,
sbom.ArtifactTypeSBOM: icon.DigestOfIconAccSBOM,
model.ArtifactTypeModel: icon.DigestOfIconModel,
}
)

Expand Down Expand Up @@ -219,7 +221,7 @@ func (c *controller) ensureArtifact(ctx context.Context, repository, digest stri
}

// populate the artifact type
artifact.Type = processor.Get(artifact.MediaType).GetArtifactType(ctx, artifact)
artifact.Type = processor.Get(artifact.ResolveArtifactType()).GetArtifactType(ctx, artifact)

// create it
// use orm.WithTransaction here to avoid the issue:
Expand Down Expand Up @@ -437,7 +439,7 @@ func (c *controller) deleteDeeply(ctx context.Context, id int64, isRoot, isAcces
// use orm.WithTransaction here to avoid the issue:
// https://www.postgresql.org/message-id/002e01c04da9%24a8f95c20%2425efe6c1%40lasting.ro
if err = orm.WithTransaction(func(ctx context.Context) error {
_, err = c.artrashMgr.Create(ctx, &model.ArtifactTrash{
_, err = c.artrashMgr.Create(ctx, &trashmodel.ArtifactTrash{
MediaType: art.MediaType,
ManifestMediaType: art.ManifestMediaType,
RepositoryName: art.RepositoryName,
Expand Down Expand Up @@ -599,7 +601,7 @@ func (c *controller) GetAddition(ctx context.Context, artifactID int64, addition
if err != nil {
return nil, err
}
return processor.Get(artifact.MediaType).AbstractAddition(ctx, artifact, addition)
return processor.Get(artifact.ResolveArtifactType()).AbstractAddition(ctx, artifact, addition)
}

func (c *controller) AddLabel(ctx context.Context, artifactID int64, labelID int64) (err error) {
Expand Down Expand Up @@ -757,7 +759,7 @@ func (c *controller) populateLabels(ctx context.Context, art *Artifact) {
}

func (c *controller) populateAdditionLinks(ctx context.Context, artifact *Artifact) {
types := processor.Get(artifact.MediaType).ListAdditionTypes(ctx, &artifact.Artifact)
types := processor.Get(artifact.ResolveArtifactType()).ListAdditionTypes(ctx, &artifact.Artifact)
if len(types) > 0 {
version := lib.GetAPIVersion(ctx)
for _, t := range types {
Expand Down
106 changes: 106 additions & 0 deletions src/controller/artifact/processor/model/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
"context"
"encoding/json"

modelspec "github.com/CloudNativeAI/model-spec/specs-go/v1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"

ps "github.com/goharbor/harbor/src/controller/artifact/processor"
"github.com/goharbor/harbor/src/controller/artifact/processor/base"
"github.com/goharbor/harbor/src/controller/artifact/processor/model/parser"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/artifact"
)

// const definitions
const (
// ArtifactTypeModel defines the artifact type for AI model.
ArtifactTypeModel = "MODEL"

// AdditionTypeReadme defines the addition type readme for API.
AdditionTypeReadme = "README.MD"
// AdditionTypeLicense defines the addition type license for API.
AdditionTypeLicense = "LICENSE"
// AdditionTypeFiles defines the addition type files for API.
AdditionTypeFiles = "FILES"
)

func init() {
pc := &processor{
ManifestProcessor: base.NewManifestProcessor(),
}

if err := ps.Register(pc, modelspec.ArtifactTypeModelManifest); err != nil {
log.Errorf("failed to register processor for artifact type %s: %v", modelspec.ArtifactTypeModelManifest, err)
return
}
}

type processor struct {
*base.ManifestProcessor
}

func (p *processor) AbstractAddition(ctx context.Context, artifact *artifact.Artifact, addition string) (*ps.Addition, error) {
var additionParser parser.Parser
switch addition {
case AdditionTypeReadme:
additionParser = parser.NewReadme(p.RegCli)
case AdditionTypeLicense:
additionParser = parser.NewLicense(p.RegCli)
case AdditionTypeFiles:
additionParser = parser.NewFiles(p.RegCli)
default:
return nil, errors.New(nil).WithCode(errors.BadRequestCode).
WithMessagef("addition %s isn't supported for %s", addition, ArtifactTypeModel)
}

mf, _, err := p.RegCli.PullManifest(artifact.RepositoryName, artifact.Digest)
if err != nil {
return nil, err
}

_, payload, err := mf.Payload()
if err != nil {
return nil, err
}

manifest := &ocispec.Manifest{}
if err := json.Unmarshal(payload, manifest); err != nil {
return nil, err
}

contentType, content, err := additionParser.Parse(ctx, artifact, manifest)
if err != nil {
return nil, err
}

return &ps.Addition{
ContentType: contentType,
Content: content,
}, nil
}

func (p *processor) GetArtifactType(_ context.Context, _ *artifact.Artifact) string {
return ArtifactTypeModel
}

func (p *processor) ListAdditionTypes(_ context.Context, _ *artifact.Artifact) []string {
return []string{AdditionTypeReadme, AdditionTypeLicense, AdditionTypeFiles}
}
Loading

0 comments on commit 162737a

Please # to comment.