return index on get magifest
This commit is contained in:
@@ -33,9 +33,9 @@ func TestFile(t *testing.T) {
|
|||||||
err = db.InitDatabase()
|
err = db.InitDatabase()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
id := uuid.NewUUID()
|
id := auxuuid.NewUUID()
|
||||||
timenow := auxtool.TimeNow()
|
timenow := auxtool.TimeNow()
|
||||||
creator := uuid.NewUUID()
|
creator := auxuuid.NewUUID()
|
||||||
collection := "foo"
|
collection := "foo"
|
||||||
newFile := &descr.File{
|
newFile := &descr.File{
|
||||||
ID: id,
|
ID: id,
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ func TestGrant(t *testing.T) {
|
|||||||
err = db.InitDatabase()
|
err = db.InitDatabase()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
id := uuid.NewUUID()
|
id := auxuuid.NewUUID()
|
||||||
accountID := uuid.NewUUID()
|
accountID := auxuuid.NewUUID()
|
||||||
timenow := auxtool.TimeNow()
|
timenow := auxtool.TimeNow()
|
||||||
creator := uuid.NewUUID()
|
creator := auxuuid.NewUUID()
|
||||||
newGrant := &descr.Grant{
|
newGrant := &descr.Grant{
|
||||||
ID: id,
|
ID: id,
|
||||||
AccountID: accountID,
|
AccountID: accountID,
|
||||||
|
|||||||
+39
-16
@@ -19,12 +19,13 @@ func (db *Database) InsertManifest(ctx context.Context, manifest *descr.Manifest
|
|||||||
var err error
|
var err error
|
||||||
var request string
|
var request string
|
||||||
request = `INSERT INTO manifests(id, name, reference, contentType, payload, digest,
|
request = `INSERT INTO manifests(id, name, reference, contentType, payload, digest,
|
||||||
created_at, updated_at, created_by, updated_by)
|
created_at, updated_at, created_by, updated_by, architecture, os, variant)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`
|
||||||
_, err = db.db.Exec(request, manifest.ID, manifest.Name, manifest.Reference,
|
_, err = db.db.Exec(request, manifest.ID, manifest.Name, manifest.Reference,
|
||||||
manifest.ContentType, manifest.Payload, manifest.Digest,
|
manifest.ContentType, manifest.Payload, manifest.Digest,
|
||||||
manifest.CreatedAt, manifest.UpdatedAt,
|
manifest.CreatedAt, manifest.UpdatedAt,
|
||||||
manifest.CreatedBy, manifest.UpdatedBy)
|
manifest.CreatedBy, manifest.UpdatedBy,
|
||||||
|
manifest.Architecture, manifest.OS, manifest.Variant)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -39,12 +40,14 @@ func (db *Database) InsertManifests(ctx context.Context, manifests []*descr.Mani
|
|||||||
for _, manifest := range manifests {
|
for _, manifest := range manifests {
|
||||||
var request string
|
var request string
|
||||||
request = `INSERT INTO manifests(id, name, reference, contentType, payload, digest,
|
request = `INSERT INTO manifests(id, name, reference, contentType, payload, digest,
|
||||||
created_at, updated_at, created_by, updated_by)
|
created_at, updated_at, created_by, updated_by,
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`
|
architecture, os, variant)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`
|
||||||
_, err = tx.Exec(request, manifest.ID, manifest.Name, manifest.Reference,
|
_, err = tx.Exec(request, manifest.ID, manifest.Name, manifest.Reference,
|
||||||
manifest.ContentType, manifest.Payload, manifest.Digest,
|
manifest.ContentType, manifest.Payload, manifest.Digest,
|
||||||
manifest.CreatedAt, manifest.UpdatedAt,
|
manifest.CreatedAt, manifest.UpdatedAt,
|
||||||
manifest.CreatedBy, manifest.UpdatedBy)
|
manifest.CreatedBy, manifest.UpdatedBy,
|
||||||
|
manifest.Architecture, manifest.OS, manifest.Variant)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -62,9 +65,10 @@ func (db *Database) UpdateManifest(ctx context.Context, manifest *descr.Manifest
|
|||||||
var request string
|
var request string
|
||||||
// Manifest
|
// Manifest
|
||||||
request = `UPDATE manifests SET contentType = $1, payload = $2, digest = $3, updated_at = $4
|
request = `UPDATE manifests SET contentType = $1, payload = $2, digest = $3, updated_at = $4
|
||||||
WHERE name = $5 AND reference = $6`
|
WHERE name = $5 AND reference = $6, architecture = $7, os = $8, variant = $9`
|
||||||
_, err = db.db.Exec(request, manifest.ContentType, manifest.Payload, manifest.Digest,
|
_, err = db.db.Exec(request, manifest.ContentType, manifest.Payload, manifest.Digest,
|
||||||
manifest.UpdatedAt, manifest.Name, manifest.Reference)
|
manifest.UpdatedAt, manifest.Name, manifest.Reference,
|
||||||
|
manifest.Architecture, manifest.OS, manifest.Variant)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -80,12 +84,13 @@ func (db *Database) InsertManifestWithLayers(ctx context.Context, manifest *desc
|
|||||||
// Manifest
|
// Manifest
|
||||||
request = `
|
request = `
|
||||||
INSERT INTO manifests(id, name, reference, contentType, payload, digest,
|
INSERT INTO manifests(id, name, reference, contentType, payload, digest,
|
||||||
created_at, updated_at, created_by, updated_by)
|
created_at, updated_at, created_by, updated_by, architecture, os, variant)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);`
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);`
|
||||||
_, err = tx.Exec(request, manifest.ID, manifest.Name, manifest.Reference,
|
_, err = tx.Exec(request, manifest.ID, manifest.Name, manifest.Reference,
|
||||||
manifest.ContentType, manifest.Payload, manifest.Digest,
|
manifest.ContentType, manifest.Payload, manifest.Digest,
|
||||||
manifest.CreatedAt, manifest.UpdatedAt,
|
manifest.CreatedAt, manifest.UpdatedAt,
|
||||||
manifest.CreatedBy, manifest.UpdatedBy)
|
manifest.CreatedBy, manifest.UpdatedBy,
|
||||||
|
manifest.Architecture, manifest.OS, manifest.Variant)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -124,10 +129,11 @@ func (db *Database) UpdateManifestWithBlobs(ctx context.Context, manifest *descr
|
|||||||
|
|
||||||
// Manifest
|
// Manifest
|
||||||
request = `UPDATE manifests SET contentType = $1, payload = $2, digest = $3, updated_at = $4, updated_by = $5
|
request = `UPDATE manifests SET contentType = $1, payload = $2, digest = $3, updated_at = $4, updated_by = $5
|
||||||
WHERE name = $6 AND reference = $7`
|
WHERE name = $6 AND reference = $7, architecture = $8, os = $9, variant = $10`
|
||||||
_, err = tx.Exec(request, manifest.ContentType, manifest.Payload, manifest.Digest,
|
_, err = tx.Exec(request, manifest.ContentType, manifest.Payload, manifest.Digest,
|
||||||
manifest.UpdatedAt, manifest.UpdatedBy,
|
manifest.UpdatedAt, manifest.UpdatedBy,
|
||||||
manifest.Name, manifest.Reference)
|
manifest.Name, manifest.Reference,
|
||||||
|
manifest.Architecture, manifest.OS, manifest.Variant)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -202,20 +208,37 @@ func (db *Database) GetManifestByDigest(ctx context.Context, name, digest string
|
|||||||
return exists, manifest, err
|
return exists, manifest, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) GetManifestByReference(ctx context.Context, name, reference string) (bool, descr.Manifest, error) {
|
func (db *Database) GetManifestsByReference(ctx context.Context, name, reference string) (bool, []descr.Manifest, error) {
|
||||||
var err error
|
var err error
|
||||||
manifest := descr.Manifest{}
|
|
||||||
exists := false
|
exists := false
|
||||||
manifests := make([]descr.Manifest, 0)
|
manifests := make([]descr.Manifest, 0)
|
||||||
request := `SELECT * FROM manifests WHERE name = $1 AND reference = $2 LIMIT 1`
|
request := `SELECT * FROM manifests WHERE name = $1 AND reference = $2 LIMIT 1`
|
||||||
err = db.db.Select(&manifests, request, name, reference)
|
err = db.db.Select(&manifests, request, name, reference)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return exists, manifest, err
|
return exists, manifests, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(manifests) > 0 {
|
if len(manifests) > 0 {
|
||||||
exists = true
|
exists = true
|
||||||
|
}
|
||||||
|
return exists, manifests, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) GetManifestsByReferenceArchitecture(ctx context.Context, name, reference, architecture, os, variant string) (bool, descr.Manifest, error) {
|
||||||
|
var err error
|
||||||
|
exists := false
|
||||||
|
manifest := descr.Manifest{}
|
||||||
|
manifests := make([]descr.Manifest, 0)
|
||||||
|
request := `SELECT * FROM manifests WHERE name = $1 AND reference = $2
|
||||||
|
AND architecture = $3 AND os = $4 AND variant = $5 LIMIT 1000`
|
||||||
|
err = db.db.Select(&manifests, request, name, reference, architecture, os, variant)
|
||||||
|
if err != nil {
|
||||||
|
return exists, manifest, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(manifests) > 0 {
|
||||||
manifest = manifests[0]
|
manifest = manifests[0]
|
||||||
|
exists = true
|
||||||
}
|
}
|
||||||
return exists, manifest, err
|
return exists, manifest, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,13 @@ const schema = `
|
|||||||
created_at VARCHAR(255) NOT NULL,
|
created_at VARCHAR(255) NOT NULL,
|
||||||
updated_at VARCHAR(255) NOT NULL,
|
updated_at VARCHAR(255) NOT NULL,
|
||||||
created_by VARCHAR(255) NOT NULL,
|
created_by VARCHAR(255) NOT NULL,
|
||||||
updated_by VARCHAR(255) NOT NULL
|
updated_by VARCHAR(255) NOT NULL,
|
||||||
|
architecture VARCHAR(255) NOT NULL,
|
||||||
|
os VARCHAR(255) NOT NULL,
|
||||||
|
variant VARCHAR(255) NOT NULL
|
||||||
);
|
);
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS manifests_index
|
CREATE UNIQUE INDEX IF NOT EXISTS manifests_index
|
||||||
ON manifests(name, reference);
|
ON manifests(name, reference, architecture, os, variant);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS blobs (
|
CREATE TABLE IF NOT EXISTS blobs (
|
||||||
id VARCHAR(255) NOT NULL,
|
id VARCHAR(255) NOT NULL,
|
||||||
|
|||||||
+39
-17
@@ -48,6 +48,7 @@ func (oper *Operator) ManifestExists(ctx context.Context, params *ManifestExists
|
|||||||
}
|
}
|
||||||
|
|
||||||
var manifest descr.Manifest
|
var manifest descr.Manifest
|
||||||
|
manifests := make([]descr.Manifest, 0)
|
||||||
var exists bool
|
var exists bool
|
||||||
if stringLikeSHA256Digest(params.Reference) {
|
if stringLikeSHA256Digest(params.Reference) {
|
||||||
digest := fmt.Sprintf("%s:%s", sha256prefix, params.Reference)
|
digest := fmt.Sprintf("%s:%s", sha256prefix, params.Reference)
|
||||||
@@ -59,13 +60,14 @@ func (oper *Operator) ManifestExists(ctx context.Context, params *ManifestExists
|
|||||||
return res, http.StatusNotFound, err
|
return res, http.StatusNotFound, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exists, manifest, err = oper.mdb.GetManifestByReference(ctx, params.Name, params.Reference)
|
exists, manifests, err = oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, http.StatusInternalServerError, err
|
return res, http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
return res, http.StatusNotFound, err
|
return res, http.StatusNotFound, err
|
||||||
}
|
}
|
||||||
|
manifest = manifests[0] // TODO: tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
digest := auxoci.SHA256DigestFromString(manifest.Payload)
|
digest := auxoci.SHA256DigestFromString(manifest.Payload)
|
||||||
@@ -169,14 +171,17 @@ func (oper *Operator) PutManifest(ctx context.Context, params *PutManifestParams
|
|||||||
incomingManifest.MediaType = params.ContentType
|
incomingManifest.MediaType = params.ContentType
|
||||||
}
|
}
|
||||||
|
|
||||||
manifestExists, existengManifestDescr, err := oper.mdb.GetManifestByReference(ctx, params.Name, params.Reference)
|
name := params.Name
|
||||||
|
reference := params.Reference
|
||||||
|
arch := incomingManifest.Subject.Platform.Architecture
|
||||||
|
os := incomingManifest.Subject.Platform.OS
|
||||||
|
variant := incomingManifest.Subject.Platform.Variant
|
||||||
|
|
||||||
|
manifestExists, existengManifestDescr, err := oper.mdb.GetManifestsByReferenceArchitecture(ctx, name, reference, arch, os, variant)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, http.StatusInternalServerError, err
|
return res, http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
name := params.Name
|
|
||||||
reference := params.Reference
|
|
||||||
|
|
||||||
incomingManifestDescr, incomingLayerDescrs, err := descrsFromManifest(name, reference, incomingManifest, incomingManifestBytes)
|
incomingManifestDescr, incomingLayerDescrs, err := descrsFromManifest(name, reference, incomingManifest, incomingManifestBytes)
|
||||||
// Always check layer files for availability
|
// Always check layer files for availability
|
||||||
var blobError error
|
var blobError error
|
||||||
@@ -297,15 +302,6 @@ func (oper *Operator) GetManifest(ctx context.Context, params *GetManifestParams
|
|||||||
if !exists {
|
if !exists {
|
||||||
return res, http.StatusNotFound, err
|
return res, http.StatusNotFound, err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
exists, manifestDescr, err = oper.mdb.GetManifestByReference(ctx, params.Name, params.Reference)
|
|
||||||
if err != nil {
|
|
||||||
return res, http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
if !exists {
|
|
||||||
return res, http.StatusNotFound, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
manifestDigest := auxoci.SHA256DigestFromString(manifestDescr.Payload)
|
manifestDigest := auxoci.SHA256DigestFromString(manifestDescr.Payload)
|
||||||
res.DockerContentDigest = manifestDigest.String()
|
res.DockerContentDigest = manifestDigest.String()
|
||||||
@@ -314,6 +310,25 @@ func (oper *Operator) GetManifest(ctx context.Context, params *GetManifestParams
|
|||||||
res.ContentType = manifestDescr.ContentType
|
res.ContentType = manifestDescr.ContentType
|
||||||
res.Payload = manifestDescr.Payload
|
res.Payload = manifestDescr.Payload
|
||||||
|
|
||||||
|
} else {
|
||||||
|
exists, manifestDescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference)
|
||||||
|
if err != nil {
|
||||||
|
return res, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return res, http.StatusNotFound, err
|
||||||
|
}
|
||||||
|
index, indexBytes, err := indexFromManigestDescrs(manifestDescrs)
|
||||||
|
if err != nil {
|
||||||
|
return res, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
indexDigest := auxoci.SHA256DigestFromString(indexBytes)
|
||||||
|
res.DockerContentDigest = indexDigest.String()
|
||||||
|
|
||||||
|
res.ContentLength = strconv.FormatInt(int64(len(indexBytes)), 10)
|
||||||
|
res.ContentType = index.MediaType
|
||||||
|
res.Payload = string(indexBytes)
|
||||||
|
}
|
||||||
return res, http.StatusOK, err
|
return res, http.StatusOK, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,9 +367,13 @@ func (oper *Operator) DeleteManifest(ctx context.Context, params *DeleteManifest
|
|||||||
return res, http.StatusNotFound, err
|
return res, http.StatusNotFound, err
|
||||||
}
|
}
|
||||||
reference = manifestDescr.Reference
|
reference = manifestDescr.Reference
|
||||||
|
err = oper.deleteManifestObjects(ctx, params.Name, reference)
|
||||||
|
if err != nil {
|
||||||
|
return res, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check manifest by name and reference
|
// Check manifest by name and reference
|
||||||
exists, manifestDescr, err = oper.mdb.GetManifestByReference(ctx, params.Name, params.Reference)
|
exists, manifestDescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, http.StatusInternalServerError, err
|
return res, http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
@@ -362,12 +381,15 @@ func (oper *Operator) DeleteManifest(ctx context.Context, params *DeleteManifest
|
|||||||
return res, http.StatusNotFound, err
|
return res, http.StatusNotFound, err
|
||||||
}
|
}
|
||||||
reference = params.Reference
|
reference = params.Reference
|
||||||
}
|
for _, manifestDescr := range manifestDescrs {
|
||||||
// Get blobs associated with the name
|
reference = manifestDescr.Reference
|
||||||
err = oper.deleteManifestObjects(ctx, params.Name, reference)
|
err = oper.deleteManifestObjects(ctx, params.Name, reference)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, http.StatusInternalServerError, err
|
return res, http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get blobs associated with the name
|
||||||
return res, http.StatusAccepted, err
|
return res, http.StatusAccepted, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
package operator
|
package operator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"mstore/pkg/auxoci"
|
||||||
"mstore/pkg/auxtool"
|
"mstore/pkg/auxtool"
|
||||||
"mstore/pkg/auxuuid"
|
"mstore/pkg/auxuuid"
|
||||||
"mstore/pkg/descr"
|
"mstore/pkg/descr"
|
||||||
@@ -18,6 +21,42 @@ import (
|
|||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func indexFromManigestDescrs(manifestDescrs []descr.Manifest) (ocispec.Index, string, error) {
|
||||||
|
var err error
|
||||||
|
var payload string
|
||||||
|
index := ocispec.Index{
|
||||||
|
MediaType: ocispec.MediaTypeImageIndex,
|
||||||
|
Manifests: make([]ocispec.Descriptor, 0),
|
||||||
|
}
|
||||||
|
index.Versioned.SchemaVersion = 2
|
||||||
|
for _, manifestDescr := range manifestDescrs {
|
||||||
|
var ociManifest ocispec.Manifest
|
||||||
|
|
||||||
|
ociManifest.Subject = &ocispec.Descriptor{}
|
||||||
|
ociManifest.Subject.Platform = &ocispec.Platform{}
|
||||||
|
ociManifest.Config = ocispec.Descriptor{}
|
||||||
|
ociManifest.Config.Platform = &ocispec.Platform{}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(manifestDescr.Payload), &ociManifest)
|
||||||
|
if err != nil {
|
||||||
|
return index, payload, err
|
||||||
|
}
|
||||||
|
descriptor := ocispec.Descriptor{
|
||||||
|
MediaType: ocispec.MediaTypeImageManifest,
|
||||||
|
Digest: auxoci.SHA256DigestFromString(manifestDescr.Payload),
|
||||||
|
Size: int64(len(manifestDescr.Payload)),
|
||||||
|
Platform: ociManifest.Subject.Platform,
|
||||||
|
}
|
||||||
|
index.Manifests = append(index.Manifests, descriptor)
|
||||||
|
}
|
||||||
|
indexBytes, err := json.Marshal(index)
|
||||||
|
if err != nil {
|
||||||
|
return index, payload, err
|
||||||
|
}
|
||||||
|
payload = string(indexBytes)
|
||||||
|
return index, payload, err
|
||||||
|
}
|
||||||
|
|
||||||
func descrsFromManifest(name, reference string, manifest *ocispec.Manifest, rawManifest []byte) (descr.Manifest, []descr.Blob, error) {
|
func descrsFromManifest(name, reference string, manifest *ocispec.Manifest, rawManifest []byte) (descr.Manifest, []descr.Blob, error) {
|
||||||
var err error
|
var err error
|
||||||
manifestDescr := descr.Manifest{}
|
manifestDescr := descr.Manifest{}
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ import (
|
|||||||
|
|
||||||
func ParseOCIManifest(rawManifest []byte) (*ocispec.Manifest, error) {
|
func ParseOCIManifest(rawManifest []byte) (*ocispec.Manifest, error) {
|
||||||
manifest := &ocispec.Manifest{}
|
manifest := &ocispec.Manifest{}
|
||||||
|
manifest.Subject = &ocispec.Descriptor{}
|
||||||
|
manifest.Subject.Platform = &ocispec.Platform{}
|
||||||
|
manifest.Config = ocispec.Descriptor{}
|
||||||
|
manifest.Config.Platform = &ocispec.Platform{}
|
||||||
|
|
||||||
err := json.Unmarshal(rawManifest, &manifest)
|
err := json.Unmarshal(rawManifest, &manifest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Manifest parsing error: %v", err)
|
err = fmt.Errorf("Manifest parsing error: %v", err)
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ type Manifest struct {
|
|||||||
UpdatedAt string `db:"updated_at" json:"updatedAt"`
|
UpdatedAt string `db:"updated_at" json:"updatedAt"`
|
||||||
CreatedBy string `db:"created_by" json:"createdBy,omitempty"`
|
CreatedBy string `db:"created_by" json:"createdBy,omitempty"`
|
||||||
UpdatedBy string `db:"updated_by" json:"updatedBy,omitempty"`
|
UpdatedBy string `db:"updated_by" json:"updatedBy,omitempty"`
|
||||||
|
Architecture string `db:"architecture" json:"architecture,omitempty"`
|
||||||
|
OS string `db:"os" json:"os,omitempty"`
|
||||||
|
Variant string `db:"variant" json:"variant,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tags struct {
|
type Tags struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user