Skip to content

Commit

Permalink
Merge branch 'master' into error_handling_registration
Browse files Browse the repository at this point in the history
Signed-off-by: Nithish Karthik <[email protected]>
  • Loading branch information
humblenginr authored Aug 8, 2024
2 parents a74edb0 + b1794be commit 91ccbc5
Show file tree
Hide file tree
Showing 13 changed files with 393 additions and 53 deletions.
6 changes: 3 additions & 3 deletions models/meshmodel/core/v1alpha2/relationship.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (
const RelationshipSchemaVersion = "relationships.meshery.io/v1alpha2"

type RelationshipDefinition struct {
ID uuid.UUID `json:"id"`
v1beta1.VersionMeta
Kind string `json:"kind,omitempty" yaml:"kind"`
ID uuid.UUID `json:"id"`
v1beta1.VersionMeta `json:",inline" yaml:",inline"`
Kind string `json:"kind,omitempty" yaml:"kind"`
// The property has been named RelationshipType instead of Type to avoid collision from Type() function, which enables support for dynamic type.
// Though, the column name and the json representation is "type".
RelationshipType string `json:"type" yaml:"type" gorm:"type"`
Expand Down
12 changes: 6 additions & 6 deletions models/meshmodel/core/v1beta1/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
)

type VersionMeta struct {
SchemaVersion string `json:"schemaVersion,omitempty" yaml:"schemaVersion"`
Version string `json:"version,omitempty" yaml:"version"`
SchemaVersion string `json:"schemaVersion,omitempty" yaml:"schemaVersion" gorm:"column:schema_version"`
Version string `json:"version,omitempty" yaml:"version" gorm:"column:version"`
}

type TypeMeta struct {
Expand All @@ -40,10 +40,10 @@ type ComponentEntity struct {

// swagger:response ComponentDefinition
type ComponentDefinition struct {
ID uuid.UUID `json:"id"`
VersionMeta
DisplayName string `json:"displayName" gorm:"displayName"`
Description string `json:"description" gorm:"description"`
ID uuid.UUID `json:"id"`
VersionMeta `json:",inline" yaml:",inline"`
DisplayName string `json:"displayName" gorm:"column:display_name"`
Description string `json:"description" gorm:"column:description"`
Format ComponentFormat `json:"format" yaml:"format"`
ModelID uuid.UUID `json:"-" gorm:"index:idx_component_definition_dbs_model_id,column:model_id"`
Model Model `json:"model" gorm:"foreignKey:ModelID;references:ID"`
Expand Down
6 changes: 3 additions & 3 deletions models/meshmodel/core/v1beta1/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ type ModelEntity struct {

// swagger:response Model
type Model struct {
ID uuid.UUID `json:"id"`
VersionMeta
ID uuid.UUID `json:"id"`
VersionMeta `yaml:",inline"`

Name string `json:"name" gorm:"modelName"`
DisplayName string `json:"displayName"`
Description string `json:"description" gorm:"description"`
Expand Down Expand Up @@ -97,7 +98,6 @@ func (m *Model) Create(db *database.Handler, hostID uuid.UUID) (uuid.UUID, error
m.ID = modelID
m.CategoryID = id
m.RegistrantID = hostID
m.Status = entity.Enabled
err = db.Omit(clause.Associations).Create(&m).Error
if err != nil {
return uuid.UUID{}, err
Expand Down
46 changes: 33 additions & 13 deletions models/meshmodel/registry/v1beta1/model_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

type ModelFilter struct {
Id string
Id string
Name string
Registrant string //name of the registrant for a given model
DisplayName string //If Name is already passed, avoid passing Display name unless greedy=true, else the filter will translate to an AND returning only the models where name and display name match exactly. Ignore, if this behavior is expected.
Expand Down Expand Up @@ -49,18 +49,42 @@ func countUniqueModels(models []v1beta1.Model) int {
}

func (mf *ModelFilter) GetById(db *database.Handler) (entity.Entity, error) {
m := &v1beta1.Model{}
err := db.First(m, "id = ?", mf.Id).Error
m := &v1beta1.Model{}

// Retrieve the model by ID
err := db.First(m, "id = ?", mf.Id).Error
if err != nil {
return nil, registry.ErrGetById(err, mf.Id)
}
return m, err
}

// Include components if requested
if mf.Components {
var components []v1beta1.ComponentDefinition
componentFinder := db.Model(&v1beta1.ComponentDefinition{}).
Select("component_definition_dbs.id, component_definition_dbs.component, component_definition_dbs.display_name, component_definition_dbs.metadata, component_definition_dbs.schema_version, component_definition_dbs.version").
Where("component_definition_dbs.model_id = ?", m.ID)
if err := componentFinder.Scan(&components).Error; err != nil {
return nil, err
}
m.Components = components
}

func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, error) {
// Include relationships if requested
if mf.Relationships {
var relationships []v1alpha2.RelationshipDefinition
relationshipFinder := db.Model(&v1alpha2.RelationshipDefinition{}).
Select("relationship_definition_dbs.*").
Where("relationship_definition_dbs.model_id = ?", m.ID)
if err := relationshipFinder.Scan(&relationships).Error; err != nil {
return nil, err
}
m.Relationships = relationships
}

return m, nil
}

func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, error) {
var modelWithCategories []v1beta1.Model

finder := db.Model(&v1beta1.Model{}).Preload("Category").Preload("Registrant").
Expand Down Expand Up @@ -129,17 +153,13 @@ func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, e
}

status := "enabled"
if mf.Status != "" {

if mf.Status != "" {
status = mf.Status
}

finder = finder.Where("model_dbs.status = ?", status)

if mf.Status != "" {
finder = finder.Where("model_dbs.status = ?", mf.Status)
}

includeComponents = mf.Components
includeRelationships = mf.Relationships

Expand All @@ -157,7 +177,7 @@ func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, e
if includeComponents {
var components []v1beta1.ComponentDefinition
finder := db.Model(&v1beta1.ComponentDefinition{}).
Select("component_definition_dbs.id, component_definition_dbs.component, component_definition_dbs.display_name, component_definition_dbs.metadata").
Select("component_definition_dbs.id, component_definition_dbs.component, component_definition_dbs.display_name, component_definition_dbs.metadata, component_definition_dbs.schema_version, component_definition_dbs.version").
Where("component_definition_dbs.model_id = ?", _modelDB.ID)
if err := finder.Scan(&components).Error; err != nil {
return nil, 0, 0, err
Expand Down
28 changes: 26 additions & 2 deletions models/oci/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,24 @@ var (
ErrAddLayerCode = "meshkit-11247"
ErrTaggingPackageCode = "meshkit-11248"
ErrPushingPackageCode = "meshkit-11249"
ErrSeekFailedCode = "replace_me"
ErrCreateLayerCode = "replace_me"
ErrSavingImageCode = "replace_me"
)

func ErrAppendingLayer(err error) error {
return errors.New(ErrAppendingLayerCode, errors.Alert, []string{"appending content to artifact failed"}, []string{err.Error()}, []string{"layer is not compatible with the base image"}, []string{"Try using a different base image", "use a different media type for the layer"})
}

func ErrSavingImage(err error) error {
return errors.New(
ErrSavingImageCode,
errors.Alert,
[]string{"Failed to save image"},
[]string{"An error occurred while saving the image."},
[]string{"Possible issues with file system, insufficient disk space, , other IO errors."},
[]string{"Check the file system permissions and available disk space.", "Ensure the file path is correct and accessible.", "Check for any underlying IO errors."},
)
}
func ErrReadingFile(err error) error {
return errors.New(ErrReadingFileCode, errors.Alert, []string{"reading file failed"}, []string{err.Error()}, []string{"failed to read the file", "Insufficient permissions"}, []string{"Try using a different file", "check if appropriate read permissions are given to the file"})
}
Expand All @@ -43,7 +55,16 @@ func ErrGettingLayer(err error) error {
func ErrCompressingLayer(err error) error {
return errors.New(ErrCompressingLayerCode, errors.Alert, []string{"compressing layer failed"}, []string{err.Error()}, []string{"failed to compress the layer"}, []string{"Try using a different layer", "check if layers are compatible with the base image"})
}

func ErrCreateLayer(err error) error {
return errors.New(
ErrCreateLayerCode,
errors.Alert,
[]string{"Failed to create layer"},
[]string{"An error occurred while creating the layer for the image."},
[]string{"Possible issues with file system, incorrect layer type, or other IO errors."},
[]string{"Check the file system permissions and paths.", "Ensure the layer type is correct.", "Check for any underlying IO errors."},
)
}
func ErrUnTaringLayer(err error) error {
return errors.New(ErrUnTaringLayerCode, errors.Alert, []string{"untaring layer failed"}, []string{err.Error()}, []string{"failed to untar the layer"}, []string{"Try using a different layer", "check if image is not malformed"})
}
Expand Down Expand Up @@ -83,3 +104,6 @@ func ErrTaggingPackage(err error) error {
func ErrPushingPackage(err error) error {
return errors.New(ErrPushingPackageCode, errors.Alert, []string{"pushing package failed"}, []string{err.Error()}, []string{"failed to push the package"}, []string{"Try using a different tag", "check if package is not malformed"})
}
func ErrSeekFailed(err error) error {
return errors.New(ErrSeekFailedCode, errors.Alert, []string{"Unable to reset the position within the OCI data."}, []string{err.Error()}, []string{"The function attempted to move to the start of the data but failed. This could happen if the data is corrupted or not in the expected format."}, []string{"Ensure the input data is a valid OCI archive and try again. Check if the data is compressed correctly and is not corrupted."})
}
2 changes: 1 addition & 1 deletion models/oci/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func BuildImage(sourcePath string, opts ...BuildOption) (gcrv1.Image, error) {

layer, err := createLayer(sourcePath, o.layerType, o.layerOpts)
if err != nil {
return nil, err
return nil, ErrCreateLayer(err)
}

if o.meta.Created == "" {
Expand Down
88 changes: 87 additions & 1 deletion models/oci/utils.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package oci

import (
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"

archiveTar "archive/tar"

"github.com/fluxcd/pkg/tar"
"github.com/google/go-containerregistry/pkg/crane"
gcrv1 "github.com/google/go-containerregistry/pkg/v1"
Expand All @@ -28,7 +34,7 @@ func SaveOCIArtifact(img gcrv1.Image, artifactPath, name string) error {
repoWithTag := fmt.Sprintf("%s:%s", name, "latest") // TODO: Add support to make this dynamic from user input
err := crane.Save(img, repoWithTag, artifactPath)
if err != nil {
return err
return ErrSavingImage(err)
}

return nil
Expand Down Expand Up @@ -63,3 +69,83 @@ func UnCompressOCIArtifact(source, destination string) error {

return nil
}

// ValidateOCIArtifact validates the OCI artifact tarball using go-containerregistry's validate function
func ValidateOCIArtifact(tarballPath string) error {
img, err := tarball.ImageFromPath(tarballPath, nil)
if err != nil {
return err
}

return validate.Image(img)
}

// IsOCIArtifact checks if the tarball is an OCI artifact by looking for manifest.json or index.json
func IsOCIArtifact(data []byte) bool {
reader := bytes.NewReader(data)
var tr *archiveTar.Reader

if gzr, err := gzip.NewReader(reader); err == nil {
defer gzr.Close()
tr = archiveTar.NewReader(gzr)
} else {
_, err := reader.Seek(0, io.SeekStart)
if err != nil {
return false
}
tr = archiveTar.NewReader(reader)
}

for {
header, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return false
}

if header.Name == "manifest.json" || header.Name == "index.json" {
return true
}
}

return false
}

func ExtractAndValidateManifest(data []byte) error {
reader := bytes.NewReader(data)
var tr *archiveTar.Reader

if gzr, err := gzip.NewReader(reader); err == nil {
defer gzr.Close()
tr = archiveTar.NewReader(gzr)
} else {
_, err := reader.Seek(0, io.SeekStart)
if err != nil {
return ErrSeekFailed(err)
}
tr = archiveTar.NewReader(reader)
}

for {
header, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}

if header.Name == "manifest.json" {
var manifest []map[string]interface{}
if err := json.NewDecoder(tr).Decode(&manifest); err != nil {
return fmt.Errorf("failed to decode manifest.json: %w", err)
}
fmt.Println("manifest.json is valid:", manifest)
return nil
}
}

return fmt.Errorf("manifest.json not found in tarball")
}
Loading

0 comments on commit 91ccbc5

Please sign in to comment.