zotregistry.dev/zot@v1.4.4-0.20240314164342-eec277e14d20/pkg/extensions/search/convert/annotations.go (about)

     1  package convert
     2  
     3  import (
     4  	"time"
     5  
     6  	ispec "github.com/opencontainers/image-spec/specs-go/v1"
     7  )
     8  
     9  const (
    10  	// See https://github.com/opencontainers/image-spec/blob/main/annotations.md#back-compatibility-with-label-schema
    11  	AnnotationLabels             = "org.label-schema.labels"
    12  	LabelAnnotationCreated       = "org.label-schema.build-date"
    13  	LabelAnnotationVendor        = "org.label-schema.vendor"
    14  	LabelAnnotationDescription   = "org.label-schema.description"
    15  	LabelAnnotationLicenses      = "org.label-schema.license"
    16  	LabelAnnotationTitle         = "org.label-schema.name"
    17  	LabelAnnotationDocumentation = "org.label-schema.usage"
    18  	LabelAnnotationSource        = "org.label-schema.vcs-url"
    19  )
    20  
    21  type ImageAnnotations struct {
    22  	Description   string
    23  	Created       *time.Time
    24  	Licenses      string
    25  	Title         string
    26  	Documentation string
    27  	Source        string
    28  	Labels        string
    29  	Vendor        string
    30  	Authors       string
    31  }
    32  
    33  /*
    34  	OCI annotation/label with backwards compatibility
    35  
    36  arg can be either labels or annotations
    37  https://github.com/opencontainers/image-spec/blob/main/annotations.md.
    38  */
    39  func GetAnnotationValue(annotations map[string]string, annotationKey, labelKey string) string {
    40  	value, ok := annotations[annotationKey]
    41  	if !ok || value == "" {
    42  		value, ok = annotations[labelKey]
    43  		if !ok {
    44  			value = ""
    45  		}
    46  	}
    47  
    48  	return value
    49  }
    50  
    51  func GetCreated(annotations map[string]string) *time.Time {
    52  	createdStr := GetAnnotationValue(annotations, ispec.AnnotationCreated, LabelAnnotationCreated)
    53  
    54  	created, err := time.Parse(time.RFC3339, createdStr)
    55  	if err != nil {
    56  		return nil
    57  	}
    58  
    59  	return &created
    60  }
    61  
    62  func GetDescription(annotations map[string]string) string {
    63  	return GetAnnotationValue(annotations, ispec.AnnotationDescription, LabelAnnotationDescription)
    64  }
    65  
    66  func GetLicenses(annotations map[string]string) string {
    67  	return GetAnnotationValue(annotations, ispec.AnnotationLicenses, LabelAnnotationLicenses)
    68  }
    69  
    70  func GetVendor(annotations map[string]string) string {
    71  	return GetAnnotationValue(annotations, ispec.AnnotationVendor, LabelAnnotationVendor)
    72  }
    73  
    74  func GetAuthors(annotations map[string]string) string {
    75  	authors := annotations[ispec.AnnotationAuthors]
    76  
    77  	return authors
    78  }
    79  
    80  func GetTitle(annotations map[string]string) string {
    81  	return GetAnnotationValue(annotations, ispec.AnnotationTitle, LabelAnnotationTitle)
    82  }
    83  
    84  func GetDocumentation(annotations map[string]string) string {
    85  	return GetAnnotationValue(annotations, ispec.AnnotationDocumentation, LabelAnnotationDocumentation)
    86  }
    87  
    88  func GetSource(annotations map[string]string) string {
    89  	return GetAnnotationValue(annotations, ispec.AnnotationSource, LabelAnnotationSource)
    90  }
    91  
    92  func GetCategories(labels map[string]string) string {
    93  	categories := labels[AnnotationLabels]
    94  
    95  	return categories
    96  }
    97  
    98  func GetAnnotations(annotations, labels map[string]string) ImageAnnotations {
    99  	created := GetCreated(annotations)
   100  	if created == nil {
   101  		created = GetCreated(labels)
   102  	}
   103  
   104  	description := GetDescription(annotations)
   105  	if description == "" {
   106  		description = GetDescription(labels)
   107  	}
   108  
   109  	title := GetTitle(annotations)
   110  	if title == "" {
   111  		title = GetTitle(labels)
   112  	}
   113  
   114  	documentation := GetDocumentation(annotations)
   115  	if documentation == "" {
   116  		documentation = GetDocumentation(labels)
   117  	}
   118  
   119  	source := GetSource(annotations)
   120  	if source == "" {
   121  		source = GetSource(labels)
   122  	}
   123  
   124  	licenses := GetLicenses(annotations)
   125  	if licenses == "" {
   126  		licenses = GetLicenses(labels)
   127  	}
   128  
   129  	categories := GetCategories(annotations)
   130  	if categories == "" {
   131  		categories = GetCategories(labels)
   132  	}
   133  
   134  	vendor := GetVendor(annotations)
   135  	if vendor == "" {
   136  		vendor = GetVendor(labels)
   137  	}
   138  
   139  	authors := GetAuthors(annotations)
   140  	if authors == "" {
   141  		authors = GetAuthors(labels)
   142  	}
   143  
   144  	return ImageAnnotations{
   145  		Created:       created,
   146  		Description:   description,
   147  		Title:         title,
   148  		Documentation: documentation,
   149  		Source:        source,
   150  		Licenses:      licenses,
   151  		Labels:        categories,
   152  		Vendor:        vendor,
   153  		Authors:       authors,
   154  	}
   155  }
   156  
   157  func GetIndexAnnotations(
   158  	indexAnnotations map[string]string,
   159  	annotationsFromManifest *ImageAnnotations,
   160  ) ImageAnnotations {
   161  	created := GetCreated(indexAnnotations)
   162  	if created == nil {
   163  		created = annotationsFromManifest.Created
   164  	}
   165  
   166  	description := GetDescription(indexAnnotations)
   167  	if description == "" {
   168  		description = annotationsFromManifest.Description
   169  	}
   170  
   171  	title := GetTitle(indexAnnotations)
   172  	if title == "" {
   173  		title = annotationsFromManifest.Title
   174  	}
   175  
   176  	documentation := GetDocumentation(indexAnnotations)
   177  	if documentation == "" {
   178  		documentation = annotationsFromManifest.Documentation
   179  	}
   180  
   181  	source := GetSource(indexAnnotations)
   182  	if source == "" {
   183  		source = annotationsFromManifest.Source
   184  	}
   185  
   186  	licenses := GetLicenses(indexAnnotations)
   187  	if licenses == "" {
   188  		licenses = annotationsFromManifest.Licenses
   189  	}
   190  
   191  	categories := GetCategories(indexAnnotations)
   192  	if categories == "" {
   193  		categories = annotationsFromManifest.Labels
   194  	}
   195  
   196  	vendor := GetVendor(indexAnnotations)
   197  	if vendor == "" {
   198  		vendor = annotationsFromManifest.Vendor
   199  	}
   200  
   201  	authors := GetAuthors(indexAnnotations)
   202  	if authors == "" {
   203  		authors = annotationsFromManifest.Authors
   204  	}
   205  
   206  	return ImageAnnotations{
   207  		Created:       created,
   208  		Description:   description,
   209  		Title:         title,
   210  		Documentation: documentation,
   211  		Source:        source,
   212  		Licenses:      licenses,
   213  		Labels:        categories,
   214  		Vendor:        vendor,
   215  		Authors:       authors,
   216  	}
   217  }