-
Notifications
You must be signed in to change notification settings - Fork 65
/
base_on_ubi.go
90 lines (74 loc) · 2.89 KB
/
base_on_ubi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package container
import (
"context"
"fmt"
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/check"
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/image"
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/pyxis"
cranev1 "github.com/google/go-containerregistry/pkg/v1"
)
var _ check.Check = &BasedOnUBICheck{}
// BasedOnUBICheck evaluates if the provided image is based on the Red Hat Universal Base Image.
type BasedOnUBICheck struct {
LayerHashCheckEngine layerHashChecker
}
type layerHashChecker interface {
CertifiedImagesContainingLayers(ctx context.Context, uncompressedLayerHashes []cranev1.Hash) ([]pyxis.CertImage, error)
}
func NewBasedOnUbiCheck(layerHashChecker layerHashChecker) *BasedOnUBICheck {
return &BasedOnUBICheck{LayerHashCheckEngine: layerHashChecker}
}
func (p *BasedOnUBICheck) Validate(ctx context.Context, imgRef image.ImageReference) (bool, error) {
layerHashes, err := p.getImageLayers(imgRef.ImageInfo)
if err != nil {
return false, fmt.Errorf("could not get image layers: %v", err)
}
return p.validate(ctx, layerHashes)
}
// getImageLayers returns the root filesystem DiffIDs of the image.
func (p *BasedOnUBICheck) getImageLayers(image cranev1.Image) ([]cranev1.Hash, error) {
configFile, err := image.ConfigFile()
if err != nil {
return nil, err
}
return configFile.RootFS.DiffIDs, nil
}
// certifiedImagesFound checks to make sure images exist in Red Hat Pyxis containing the uncompressed
// top layer IDs of the image under test.
func (p *BasedOnUBICheck) certifiedImagesFound(ctx context.Context, layerHashes []cranev1.Hash) (bool, error) {
certImages, err := p.LayerHashCheckEngine.CertifiedImagesContainingLayers(ctx, layerHashes)
if err != nil {
return false, fmt.Errorf("pyxis query for uncompressed top layers ids %+q failed: %w", layerHashes, err)
}
if len(certImages) >= 1 {
return true, nil
}
return false, nil
}
func (p *BasedOnUBICheck) validate(ctx context.Context, layerHashes []cranev1.Hash) (bool, error) {
hasUBIHash, err := p.certifiedImagesFound(ctx, layerHashes)
if err != nil {
return false, fmt.Errorf("unable to verify layer hashes: %v", err)
}
if hasUBIHash {
return true, nil
}
return false, nil
}
func (p *BasedOnUBICheck) Name() string {
return "BasedOnUbi"
}
func (p *BasedOnUBICheck) Metadata() check.Metadata {
return check.Metadata{
Description: "Checking if the container's base image is based upon the Red Hat Universal Base Image (UBI)",
Level: "best",
KnowledgeBaseURL: certDocumentationURL,
CheckURL: certDocumentationURL,
}
}
func (p *BasedOnUBICheck) Help() check.HelpText {
return check.HelpText{
Message: "Check BasedOnUbi encountered an error. Please review the preflight.log file for more information.",
Suggestion: "Change the FROM directive in your Dockerfile or Containerfile to FROM registry.access.redhat.com/ubi8/ubi",
}
}