github.com/apptainer/singularity@v3.1.1+incompatible/pkg/client/library/models.go (about)

     1  // Copyright (c) 2018, Sylabs Inc. All rights reserved.
     2  // This software is licensed under a 3-clause BSD license. Please consult the
     3  // LICENSE.md file distributed with the sources of this project regarding your
     4  // rights to use or distribute this software.
     5  
     6  package client
     7  
     8  import (
     9  	"sort"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/globalsign/mgo/bson"
    14  )
    15  
    16  // LibraryModels lists names of valid models in the database
    17  var LibraryModels = []string{"Entity", "Collection", "Container", "Image", "Blob"}
    18  
    19  // ModelManager - Generic interface for models which must have a bson ObjectID
    20  type ModelManager interface {
    21  	GetID() bson.ObjectId
    22  }
    23  
    24  // BaseModel - has an ID, soft deletion marker, and Audit struct
    25  type BaseModel struct {
    26  	ModelManager `bson:",omitempty" json:",omitempty"`
    27  	Deleted      bool      `bson:"deleted" json:"deleted"`
    28  	CreatedBy    string    `bson:"createdBy" json:"createdBy"`
    29  	CreatedAt    time.Time `bson:"createdAt" json:"createdAt"`
    30  	UpdatedBy    string    `bson:"updatedBy,omitempty" json:"updatedBy,omitempty"`
    31  	UpdatedAt    time.Time `bson:"updatedAt,omitempty" json:"updatedAt,omitempty"`
    32  	DeletedBy    string    `bson:"deletedBy,omitempty" json:"deletedBy,omitempty"`
    33  	DeletedAt    time.Time `bson:"deletedAt,omitempty" json:"deletedAt,omitempty"`
    34  }
    35  
    36  // IsDeleted - Convenience method to check soft deletion state if working with
    37  // an interface
    38  func (m BaseModel) IsDeleted() bool {
    39  	return m.Deleted
    40  }
    41  
    42  // GetCreated - Convenience method to get creation stamps if working with an
    43  // interface
    44  func (m BaseModel) GetCreated() (auditUser string, auditTime time.Time) {
    45  	return m.CreatedBy, m.CreatedAt
    46  }
    47  
    48  // GetUpdated - Convenience method to get update stamps if working with an
    49  // interface
    50  func (m BaseModel) GetUpdated() (auditUser string, auditTime time.Time) {
    51  	return m.UpdatedBy, m.UpdatedAt
    52  }
    53  
    54  // GetDeleted - Convenience method to get deletino stamps if working with an
    55  // interface
    56  func (m BaseModel) GetDeleted() (auditUser string, auditTime time.Time) {
    57  	return m.DeletedBy, m.DeletedAt
    58  }
    59  
    60  // Check BaseModel implements ModelManager at compile time
    61  var _ ModelManager = (*BaseModel)(nil)
    62  
    63  // Entity - Top level entry in the library, contains collections of images
    64  // for a user or group
    65  type Entity struct {
    66  	BaseModel
    67  	ID          bson.ObjectId   `bson:"_id" json:"id"`
    68  	Name        string          `bson:"name" json:"name"`
    69  	Description string          `bson:"description" json:"description"`
    70  	Collections []bson.ObjectId `bson:"collections" json:"collections"`
    71  	Size        int64           `bson:"size" json:"size"`
    72  	Quota       int64           `bson:"quota" json:"quota"`
    73  	// DefaultPrivate set true will make any new Collections in ths entity
    74  	// private at the time of creation.
    75  	DefaultPrivate bool `bson:"defaultPrivate" json:"defaultPrivate"`
    76  	// CustomData can hold a user-provided string for integration purposes
    77  	// not used by the library itself.
    78  	CustomData string `bson:"customData" json:"customData"`
    79  }
    80  
    81  // GetID - Convenience method to get model ID if working with an interface
    82  func (e Entity) GetID() bson.ObjectId {
    83  	return e.ID
    84  }
    85  
    86  // LibraryURI - library:// URI to the entity
    87  func (e Entity) LibraryURI() string {
    88  	return "library://" + e.Name
    89  }
    90  
    91  // Collection - Second level in the library, holds a collection of containers
    92  type Collection struct {
    93  	BaseModel
    94  	ID          bson.ObjectId   `bson:"_id" json:"id"`
    95  	Name        string          `bson:"name" json:"name"`
    96  	Description string          `bson:"description" json:"description"`
    97  	Entity      bson.ObjectId   `bson:"entity" json:"entity"`
    98  	Containers  []bson.ObjectId `bson:"containers" json:"containers"`
    99  	Size        int64           `bson:"size" json:"size"`
   100  	Private     bool            `bson:"private" json:"private"`
   101  	// CustomData can hold a user-provided string for integration purposes
   102  	// not used by the library itself.
   103  	CustomData string `bson:"customData" json:"customData"`
   104  	// Computed fields that will not be stored - JSON response use only
   105  	EntityName string `bson:"-" json:"entityName,omitempty"`
   106  }
   107  
   108  // GetID - Convenience method to get model ID if working with an interface
   109  func (c Collection) GetID() bson.ObjectId {
   110  	return c.ID
   111  }
   112  
   113  // LibraryURI - library:// URI to the collection
   114  func (c Collection) LibraryURI() string {
   115  	return "library://" + c.EntityName + "/" + c.Name
   116  }
   117  
   118  // Container - Third level of library. Inside a collection, holds images for
   119  // a particular container
   120  type Container struct {
   121  	BaseModel
   122  	ID            bson.ObjectId            `bson:"_id" json:"id"`
   123  	Name          string                   `bson:"name" json:"name"`
   124  	Description   string                   `bson:"description" json:"description"`
   125  	Collection    bson.ObjectId            `bson:"collection" json:"collection"`
   126  	Images        []bson.ObjectId          `bson:"images" json:"images"`
   127  	ImageTags     map[string]bson.ObjectId `bson:"imageTags" json:"imageTags"`
   128  	Size          int64                    `bson:"size" json:"size"`
   129  	DownloadCount int64                    `bson:"downloadCount" json:"downloadCount"`
   130  	// CustomData can hold a user-provided string for integration purposes
   131  	// not used by the library itself.
   132  	CustomData string `bson:"customData" json:"customData"`
   133  	// Computed fields that will not be stored - JSON response use only
   134  	Entity         bson.ObjectId `bson:"-" json:"entity,omitempty"`
   135  	EntityName     string        `bson:"-" json:"entityName,omitempty"`
   136  	CollectionName string        `bson:"-" json:"collectionName,omitempty"`
   137  }
   138  
   139  // GetID - Convenience method to get model ID if working with an interface
   140  func (c Container) GetID() bson.ObjectId {
   141  	return c.ID
   142  }
   143  
   144  // LibraryURI - library:// URI to the container
   145  func (c Container) LibraryURI() string {
   146  	return "library://" + c.EntityName + "/" + c.CollectionName + "/" + c.Name
   147  }
   148  
   149  // TagList - return a sorted space delimited list of tags
   150  func (c Container) TagList() string {
   151  	var taglist sort.StringSlice
   152  	for tag := range c.ImageTags {
   153  		taglist = append(taglist, tag)
   154  	}
   155  	taglist.Sort()
   156  	return strings.Join(taglist, " ")
   157  }
   158  
   159  // Image - Represents a Singularity image held by the library for a particular
   160  // Container
   161  type Image struct {
   162  	BaseModel
   163  	ID          bson.ObjectId `bson:"_id" json:"id"`
   164  	Hash        string        `bson:"hash" json:"hash"`
   165  	Description string        `bson:"description" json:"description"`
   166  	Container   bson.ObjectId `bson:"container" json:"container"`
   167  	Blob        bson.ObjectId `bson:"blob,omitempty" json:"blob,omitempty"`
   168  	Size        int64         `bson:"size" json:"size"`
   169  	Uploaded    bool          `bson:"uploaded" json:"uploaded"`
   170  	// CustomData can hold a user-provided string for integration purposes
   171  	// not used by the library itself.
   172  	CustomData string `bson:"customData" json:"customData"`
   173  	// Computed fields that will not be stored - JSON response use only
   174  	Entity         bson.ObjectId `bson:"-" json:"entity,omitempty"`
   175  	EntityName     string        `bson:"-" json:"entityName,omitempty"`
   176  	Collection     bson.ObjectId `bson:"-" json:"collection,omitempty"`
   177  	CollectionName string        `bson:"-" json:"collectionName,omitempty"`
   178  	ContainerName  string        `bson:"-" json:"containerName,omitempty"`
   179  }
   180  
   181  // GetID - Convenience method to get model ID if working with an interface
   182  func (img Image) GetID() bson.ObjectId {
   183  	return img.ID
   184  }
   185  
   186  // Blob - Binary data object (e.g. container image file) stored in a Backend
   187  // Uses object store bucket/key semantics
   188  type Blob struct {
   189  	BaseModel
   190  	ID          bson.ObjectId `bson:"_id" json:"id"`
   191  	Bucket      string        `bson:"bucket" json:"bucket"`
   192  	Key         string        `bson:"key" json:"key"`
   193  	Size        int64         `bson:"size" json:"size"`
   194  	ContentHash string        `bson:"contentHash" json:"contentHash"`
   195  	Status      string        `bson:"status" json:"status"`
   196  }
   197  
   198  // GetID - Convenience method to get model ID if working with an interface
   199  func (b Blob) GetID() bson.ObjectId {
   200  	return b.ID
   201  }
   202  
   203  // ImageTag - A single mapping from a string to bson ID. Not stored in the DB
   204  // but used by API calls setting tags
   205  type ImageTag struct {
   206  	Tag     string
   207  	ImageID bson.ObjectId
   208  }
   209  
   210  // TagMap - A map of tags to imageIDs for a container
   211  type TagMap map[string]bson.ObjectId