Documentation
¶
Overview ¶
Package db handles all the core database interaction It includes processors for each core type (blob, bottle, manifest, and event).
Index ¶
- Constants
- func ArtifactsCount(con *gorm.DB) int64
- func BlobDataBytes(con *gorm.DB) int64
- func BottlePulls(con *gorm.DB, dgst digest.Digest) int64
- func BottlesCount(con *gorm.DB) int64
- func ChildrenOf(digests []digest.Digest) func(db *gorm.DB) *gorm.DB
- func DeprecatedBy(dgst digest.Digest) func(db *gorm.DB) *gorm.DB
- func DeprecatesThis(dgst digest.Digest) func(db *gorm.DB) *gorm.DB
- func EventsCount(con *gorm.DB) int64
- func ExcludeDeprecated() func(db *gorm.DB) *gorm.DB
- func FilterByDigest(dgst digest.Digest, objType string) func(db *gorm.DB) *gorm.DB
- func FilterByDigests(dgsts []digest.Digest, objType string) func(db *gorm.DB) *gorm.DB
- func FilterByMetric(metricFilters []string) func(db *gorm.DB) *gorm.DB
- func FilterByParts(partDigests []digest.Digest) func(db *gorm.DB) *gorm.DB
- func FilterByPublicKeyFP(fp digest.Digest) func(db *gorm.DB) *gorm.DB
- func FilterBySelectors(selectors []string) func(db *gorm.DB) *gorm.DB
- func FilterByTrustLevel(filter string) func(db *gorm.DB) *gorm.DB
- func FindDeprecatedBy(con *gorm.DB, dgst digest.Digest) ([]digest.Digest, error)
- func FindDeprecates(con *gorm.DB, dgst digest.Digest) ([]digest.Digest, error)
- func FindDigests(con *gorm.DB, dataID uint) ([]digest.Digest, error)
- func GetSignaturesWithAnnotations(ctx context.Context, con *gorm.DB, signatures *[]Signature) (*[]Signature, error)
- func IncludeDigests(tableName string) func(db *gorm.DB) *gorm.DB
- func IncludeIsDeprecated() func(db *gorm.DB) *gorm.DB
- func IncludeNumPulls() func(db *gorm.DB) *gorm.DB
- func ManifestsCount(con *gorm.DB) int64
- func MigrateDB(ctx context.Context, conn *gorm.DB, scheme *runtime.Scheme) error
- func Open(ctx context.Context, conf v1alpha2.Database, scheme *runtime.Scheme) (*gorm.DB, error)
- func OpenPostgresDB(dsn string) (*gorm.DB, error)
- func OpenSqliteDB(dsn string) (*gorm.DB, error)
- func ParentsOf(digests []digest.Digest) func(db *gorm.DB) *gorm.DB
- func RankByDescription(description string) func(db *gorm.DB) *gorm.DB
- func RankByNumPulls() func(db *gorm.DB) *gorm.DB
- func Reprocess(ctx context.Context, con *gorm.DB, processor Processor) error
- func SearchByAuthor(author string) func(db *gorm.DB) *gorm.DB
- func SearchByRepository(bottleRepo string) func(db *gorm.DB) *gorm.DB
- func SignaturesCount(con *gorm.DB) int64
- func SortByMetric(metricName string, ascending bool) func(db *gorm.DB) *gorm.DB
- func UserPulls(con *gorm.DB, dgst digest.Digest, limit int) (map[string]int, error)
- func WithSignature(digests []digest.Digest) func(db *gorm.DB) *gorm.DB
- func WithSignatureAnnotations(annotations []string) func(db *gorm.DB) *gorm.DB
- type Annotation
- type Author
- type Base
- type Blob
- type BlobProcessor
- type Bottle
- type BottleMemberLocated
- type BottleProcessor
- type BottleRelative
- type Data
- type DefaultTrustAnchor
- type Deprecates
- type Digest
- type Digested
- type Event
- type EventProcessor
- type Generation
- func FindChildren(con *gorm.DB, digests []digest.Digest) (Generation, error)
- func FindGenerations(con *gorm.DB, bottleDigest digest.Digest, depth uint, ...) ([]Generation, error)
- func FindParents(con *gorm.DB, digests []digest.Digest) (Generation, error)
- func GetAncestors(con *gorm.DB, bottleDigest digest.Digest, depth uint) ([]Generation, error)
- func GetDescendants(con *gorm.DB, bottleDigest digest.Digest, depth uint) ([]Generation, error)
- func (g Generation) FindRelativeIdx(source Source) int
- func (g Generation) GetDigests() []digest.Digest
- func (g Generation) GetNonBottleParents() []NonBottleRelative
- func (g Generation) GetUniqueDigests() []digest.Digest
- func (g Generation) GetUnknownBottleParents(knownParents Generation) []UnknownBottleRelative
- type GormLogger
- type Label
- type Layer
- type Manifest
- type ManifestProcessor
- type Metric
- type Model
- type NextGenerationFinder
- type NonBottleRelative
- type Part
- type Processor
- type PublicArtifact
- type Relative
- type Signature
- type SignatureAnnotation
- type SignatureProcessor
- type Source
- type TrustAnchor
- type UnknownBottleRelative
Constants ¶
const BlobProcessorVersion = 3
BlobProcessorVersion is the current version of the processor code. This is incremented after each measurable change to the BlobProcessor().
const BottleProcessorVersion = 11
BottleProcessorVersion is the current version of the processor code. This is incremented after each measurable change to the BottleProcessor().
const CanonicalDigestAlgorithm = digest.Canonical
CanonicalDigestAlgorithm is the digest used internally for de-duplication and discovering aliases.
const EventProcessorVersion = 3
EventProcessorVersion is the current version of the processor code. This is incremented after each measurable change to the EventProcessor().
const ManifestProcessorVersion = 4
ManifestProcessorVersion is the current version of the processor code. This is incremented after each measurable change to the ManifestProcessor().
const SignatureProcessorVersion = 1
SignatureProcessorVersion is the current version of the processor code. This is incremented after each measurable change to the SignatureProcessor().
Variables ¶
This section is empty.
Functions ¶
func ArtifactsCount ¶
ArtifactsCount will get total count of Artifacts in DB.
func BlobDataBytes ¶
BlobDataBytes will get the total number of bytes for data blobs in DB.
func BottlePulls ¶
BottlePulls will query the events and return the pull Request count of the provided digest.
func BottlesCount ¶
BottlesCount will get total count of Bottles in DB.
func ChildrenOf ¶
ChildrenOf is a scope that will the query to children of the provided digests.
func DeprecatedBy ¶
DeprecatedBy is a scope that will query to digests that are deprecated by the provided digest.
func DeprecatesThis ¶
DeprecatesThis is a scope that will query to digests that deprecates the provided digest.
func EventsCount ¶
EventsCount will get total count of events in DB.
func ExcludeDeprecated ¶
ExcludeDeprecated is a scope that will prevent bottles from being included in the query if they are deprecated by another bottle.
func FilterByDigest ¶
FilterByDigest will use the digest to filter the query for an object type objType must "belong to" a Data record. Bottle, Manifest, Event, and PublicArtifact all have this property.
func FilterByDigests ¶
FilterByDigests will use the digests to filter the query for an object type objType must "belong to" a Data record. Bottle, Manifest, Event, and PublicArtifact all have this property.
func FilterByMetric ¶
FilterByMetric is a scope that will show bottles that have metrics matching the filter filters may take the form of "MetricName>Value", "MetricName<Value' or just "MetricName".
func FilterByParts ¶
FilterByParts is a scope that will show bottles that have all parts with provided digests.
func FilterByPublicKeyFP ¶
FilterByPublicKeyFP scopes the request to signatures with a given fingerprint.
func FilterBySelectors ¶
FilterBySelectors scopes the request to a bottle selector.
func FilterByTrustLevel ¶
FilterByTrustLevel selects records that include a trust level matching the trust level string eg "verified", "trusted".
func FindDeprecatedBy ¶
FindDeprecatedBy finds all bottles that are deprecated by the bottle with the given digest.
func FindDeprecates ¶
FindDeprecates finds all bottles that deprecates the bottle with the given digest.
func FindDigests ¶
FindDigests returns all the digests known for a given data item.
func GetSignaturesWithAnnotations ¶
func GetSignaturesWithAnnotations(ctx context.Context, con *gorm.DB, signatures *[]Signature) (*[]Signature, error)
GetSignaturesWithAnnotations takes a list of signatures without annotations and returns a slice of those same signatures with annotations included.
func IncludeDigests ¶
IncludeDigests is a scope that must be used with Digested above. It populates the DigestsCSV field.
func IncludeIsDeprecated ¶
IncludeIsDeprecated includes an extra column "is_deprecated" if the bottle is deprecated.
func IncludeNumPulls ¶
IncludeNumPulls includes an extra column "num_pulls" which is the number of pull events for the bottle.
func ManifestsCount ¶
ManifestsCount will get total count of Manifests in DB.
func Open ¶
Open opens a DB connection using URL formatting. Also migrates the database For example file:test.db, "file::memory:" or postgres://jack:secret@foo.example.com:5432,bar.example.com:5432/mydb
func OpenPostgresDB ¶
OpenPostgresDB connect to a Postgres database.
func OpenSqliteDB ¶
OpenSqliteDB connect to a sqlite database (file).
func RankByDescription ¶
RankByDescription will use FTS if available to rank order the search by best match on description.
func RankByNumPulls ¶
RankByNumPulls orders the bottles by number of pull events each has.
func Reprocess ¶
Reprocess reprocesses the given type that are out of date w.r.t. the provided processor.
func SearchByAuthor ¶
SearchByAuthor will search by Author name or email.
func SearchByRepository ¶
SearchByRepository will search by image repository that the bottle is stored in.
func SignaturesCount ¶
SignaturesCount will get total count of Artifacts in DB.
func SortByMetric ¶
SortByMetric is a scope that will sort bottles by a given metric's value.
func UserPulls ¶
UserPulls will query the events and return a mapping of username to number of pulls for a given bottle.
func WithSignature ¶
WithSignature scopes the request to bottles with a signature that has the given fingerprint.
Types ¶
type Annotation ¶
Annotation is bottle annotations.
func (Annotation) GetLocation ¶
func (a Annotation) GetLocation() string
GetLocation gets the index (key of the annotation).
type Author ¶
type Author struct {
BottleMemberLocated
Name string `gorm:"index"`
URL string // TODO should this be URI as well?
Email string `gorm:"index"`
}
Author is author information.
type Base ¶
type Base struct {
Model
ProcessorVersion uint `gorm:"index"`
Data Data // Base belongs to Data
DataID uint
}
Base is the common base for all four core types.
type BlobProcessor ¶
type BlobProcessor struct{}
BlobProcessor handles blob processing.
func (*BlobProcessor) PrimaryTable ¶
func (p *BlobProcessor) PrimaryTable() string
PrimaryTable returns primary table that this processor updates.
func (*BlobProcessor) Process ¶
func (p *BlobProcessor) Process(con *gorm.DB, base Base) error
Process converts Bottle data to the DB model for a Bottle.
func (*BlobProcessor) Version ¶
func (p *BlobProcessor) Version() uint
Version returns the processor version.
type Bottle ¶
type Bottle struct {
Base
APIVersion string
Description string
Authors []Author // Bottle has many authors
Sources []Source // Bottle has many sources
Metrics []Metric // Bottle has many metrics
PublicArtifacts []PublicArtifact // Bottle has many public_artifacts
Labels []Label // Bottle has many labels
Annotations []Annotation // Bottle has many annotations
Parts []Part // Bottle has many parts
Deprecates []Deprecates // Bottle has many deprecates
Signatures []Signature // Bottle has many signatures
}
Bottle is the metadata for a Bottle.
type BottleMemberLocated ¶
type BottleMemberLocated struct {
Model
BottleID uint // foreign key
// Location in the array from JSON
Location uint
}
BottleMemberLocated is the base for all "has many" members of a Bottle.
func (BottleMemberLocated) GetLocation ¶
func (b BottleMemberLocated) GetLocation() uint
GetLocation gets the location in the original array.
type BottleProcessor ¶
type BottleProcessor struct {
// contains filtered or unexported fields
}
BottleProcessor handles bottle processing.
func NewBottleProcessor ¶
func NewBottleProcessor(scheme *runtime.Scheme) *BottleProcessor
NewBottleProcessor creates a new BottleProcessor populating the Scheme and Codecs.
func (*BottleProcessor) PrimaryTable ¶
func (p *BottleProcessor) PrimaryTable() string
PrimaryTable returns primary table that this processor updates.
func (*BottleProcessor) Process ¶
func (p *BottleProcessor) Process(con *gorm.DB, base Base) error
Process converts Bottle data to the DB model for a Bottle.
func (*BottleProcessor) Version ¶
func (p *BottleProcessor) Version() uint
Version returns the processor version.
type BottleRelative ¶
type BottleRelative struct {
Bottle
Digested
PartSelectors selectors.LabelSelectorSet `gorm:"-"` // Optional if the relationship is partial
}
BottleRelative is a bottle relative to a bottle (parent, child, grand parent, etc.).
func (BottleRelative) GetSourceByRelative ¶
func (r BottleRelative) GetSourceByRelative(relative *BottleRelative) *Source
GetSourceByRelative returns a pointer to a source if one of the given relative's digests matches one of the sources on the BottleRelative. If no source is found, nil is returned.
func (BottleRelative) GetSourceByURI ¶
func (r BottleRelative) GetSourceByURI(uri string) *Source
GetSourceByURI returns a pointer to a source if the given URI matches one of the sources on the BottleRelative. If no source is found, nil is returned.
func (BottleRelative) MatchesSource ¶
func (r BottleRelative) MatchesSource(source Source) bool
MatchesSource returns true if the source matches this relative.
type Data ¶
type Data struct {
Model
RawData []byte
CanonicalDigest digest.Digest `gorm:"uniqueIndex"` // canonical digest is an internal only digest (like blake2 or sha3 used for de-duplication)
}
Data stores the actual data for all types (blob, bottles, manifests, events).
type DefaultTrustAnchor ¶
type DefaultTrustAnchor struct{}
DefaultTrustAnchor can be used to get a trusted value back when no other trust anchor is available.
func (*DefaultTrustAnchor) VerifyTrust ¶
func (t *DefaultTrustAnchor) VerifyTrust() bool
VerifyTrust on the DefaultTrustAnchor always returns false.
type Deprecates ¶
type Deprecates struct {
BottleMemberLocated
DeprecatedBottleDigest digest.Digest
}
Deprecates is a deprecated Bottle.
type Digest ¶
type Digest struct {
Model
Data Data // Digest belongs to Data
DataID uint
Digest digest.Digest `gorm:"uniqueIndex"` // A user provided name/digest for this data
}
Digest is a table of aliases.
type Digested ¶
type Digested struct {
DigestsCSV string `gorm:"digests_csv" json:"-"`
// DataID uint `json:"-"`
Digests []digest.Digest `gorm:"-"`
}
Digested can be added to a query type to enable.
type Event ¶
type Event struct {
Base
ManifestID uint
Manifest Manifest // Event belongs to Manifest
// While a manifest may have different digests (different algorithms) this event is specific to this manifest.
// The repository in this event may only have one (name) digest for this Manifest.
ManifestDigest digest.Digest `gorm:"index"`
BottleID uint // Event belongs to Bottle (prejoining since the association is not allowed to change)
Bottle Bottle
BottleDigest digest.Digest `gorm:"index"` // prejoin since it does not change
Action string // pull or push
Repository string
Tag string
AuthRequired bool
Bandwidth uint64
Timestamp time.Time `gorm:"index"`
Username string `gorm:"index"`
}
Event is used to record an actual download/upload event.
type EventProcessor ¶
type EventProcessor struct{}
EventProcessor handles bottle processing.
func (*EventProcessor) PrimaryTable ¶
func (p *EventProcessor) PrimaryTable() string
PrimaryTable returns primary table that this processor updates.
func (*EventProcessor) Process ¶
func (p *EventProcessor) Process(con *gorm.DB, base Base) error
Process converts Event data to the DB model.
func (*EventProcessor) Version ¶
func (p *EventProcessor) Version() uint
Version returns the processor version.
type Generation ¶
type Generation []BottleRelative
Generation represents a generation of ancestors (e.g., parents, grandparents, children).
func FindChildren ¶
FindChildren finds all children of the provides bottle digest (any number of bottles).
func FindGenerations ¶
func FindGenerations(con *gorm.DB, bottleDigest digest.Digest, depth uint, finder NextGenerationFinder) ([]Generation, error)
FindGenerations is a generic function to find multiple generations.
func FindParents ¶
FindParents finds all parents of the provides bottle digest (any number of bottles).
func GetAncestors ¶
GetAncestors returns all ancestors Input: a bottle digest and depth (1 = parents, 2 = grandparents, etc.) Output: a double-slice where each outer slice index indicates the generation, i.e. 0 = parents, etc.
func GetDescendants ¶
GetDescendants returns all descendants Input: a bottle digest and depth (1 = children, 2 = grandchildren, etc.) Output: a double-slice where each outer slice index indicates the generation, i.e. 0 = children, etc.
func (Generation) FindRelativeIdx ¶
func (g Generation) FindRelativeIdx(source Source) int
FindRelativeIdx finds the relative that matches the source in this generation.
func (Generation) GetDigests ¶
func (g Generation) GetDigests() []digest.Digest
GetDigests returns all the bottle digests for this generation (the result may contain duplicate digests).
func (Generation) GetNonBottleParents ¶
func (g Generation) GetNonBottleParents() []NonBottleRelative
GetNonBottleParents extracts the non-bottle URIs.
func (Generation) GetUniqueDigests ¶
func (g Generation) GetUniqueDigests() []digest.Digest
GetUniqueDigests returns all the bottle digests for this generation (the result will not contain duplicate digests).
func (Generation) GetUnknownBottleParents ¶
func (g Generation) GetUnknownBottleParents(knownParents Generation) []UnknownBottleRelative
GetUnknownBottleParents extracts the unknown bottle digests from a generation.
type GormLogger ¶
type GormLogger interface {
logger.Interface
IgnoreRecordNotFoundError(bool) GormLogger
SlowThreshold(time.Duration) GormLogger
}
GormLogger is an interface that also implements the gorm logger interface (with a few more functions).
func NewGormLogger ¶
func NewGormLogger() GormLogger
NewGormLogger creates a GORM compatible logger that actually logs to the given logr.Logger.
type Label ¶
type Label struct {
Model
BottleID uint
Key string `gorm:"index"` // unique per bottle
Value string `gorm:"index"`
NumericValue float64 `gorm:"index" json:"-"` // We drop this is JSON marshalling to avoid issues with logging
}
Label is bottle labels.
func (*Label) BeforeSave ¶
BeforeSave is called before the struct is saved to the DB to convert the value to a float if possible.
func (Label) GetLocation ¶
GetLocation gets the index (key of the label).
type Layer ¶
type Layer struct {
Model
ManifestID uint
Location uint
Digest digest.Digest `gorm:"index"` // This is not tracked by the telemetry server so it is just a string (not a reference to a Digest record)
}
Layer is a manifest layer.
func (Layer) GetLocation ¶
GetLocation gets the index (key of the annotation).
type Manifest ¶
type Manifest struct {
Base
BottleID uint
Bottle Bottle // Manifest belongs to Bottle
BottleDigest digest.Digest `gorm:"index"`
Layers []Layer // Bottle has many layers
}
Manifest is the OCI manifest v2 and points to a Bottle.
type ManifestProcessor ¶
type ManifestProcessor struct{}
ManifestProcessor handles bottle processing.
func (*ManifestProcessor) PrimaryTable ¶
func (p *ManifestProcessor) PrimaryTable() string
PrimaryTable returns primary table that this processor updates.
func (*ManifestProcessor) Process ¶
func (p *ManifestProcessor) Process(con *gorm.DB, base Base) error
Process converts Manifest data to the DB model.
func (*ManifestProcessor) Version ¶
func (p *ManifestProcessor) Version() uint
Version returns the processor version.
type Metric ¶
type Metric struct {
BottleMemberLocated
Name string // unique per bottle
Description string
Value float64
}
Metric is metrics on Bottles.
type Model ¶
Model is the base of all records.
func (Model) GetPrimaryKey ¶
GetPrimaryKey gets the primary key.
func (*Model) SetPrimaryKey ¶
SetPrimaryKey sets the primary key.
type NextGenerationFinder ¶
NextGenerationFinder is a function that finds the next generation from the given digests (either up or down the family tree).
type NonBottleRelative ¶
type NonBottleRelative struct {
URI string
}
NonBottleRelative represents a relative that is not a bottle but instead a URI of some other kind.
func (NonBottleRelative) MatchesSource ¶
func (u NonBottleRelative) MatchesSource(source Source) bool
MatchesSource returns true if the source matches this relative.
type Part ¶
type Part struct {
BottleMemberLocated
Name string // unique per bottle
Size uint64
Digest digest.Digest `gorm:"index"` // we do not guarantee this exists in the telemetry server so this is just a string, not a Digest and DigestID
// LabelStr is stored in the DB but code is expected to use Labels directly.
LabelsStr string `json:"-"`
Labels map[string]string `gorm:"-"`
}
Part is a data part of a Bottle.
type Processor ¶
type Processor interface {
PrimaryTable() string
Process(con *gorm.DB, base Base) error
Version() uint
}
Processor knows how to process it's type to conver the raw data to a DB model.
type PublicArtifact ¶
type PublicArtifact struct {
BottleMemberLocated
Name string
MediaType string
Path string `gorm:"index"` // unique per bottle
Data Data // PublicArtifact belongs to Data
DataID uint
// Digest is the digest of the artifact.
// We need to preserve the digest used by the bottle to reference this artifact.
Digest digest.Digest // `gorm:"index"` we might want an index here
}
PublicArtifact is metadata about a PublicArtifact as specified in the Bottle.
func FindArtifact ¶
func FindArtifact(con *gorm.DB, bottleDigest digest.Digest, artifactPath string) (*PublicArtifact, error)
FindArtifact returns the artifact by bottle and path.
type Relative ¶
type Relative interface {
BottleRelative | NonBottleRelative | UnknownBottleRelative
}
Relative is a type constraint for any relative of a bottle.
type Signature ¶
type Signature struct {
Base
ManifestID uint
Manifest Manifest // Event belongs to Manifest
// While a manifest may have different digests (different algorithms) this signature is specific to this manifest.
// The repository in this signature may only have one (name) digest for this Manifest.
ManifestDigest digest.Digest `gorm:"index"`
BottleID uint // Signature belongs to Bottle (prejoining since the association is not allowed to change)
Bottle Bottle
BottleDigest digest.Digest `gorm:"index"` // prejoin since it does not change
SignatureType string // currently dev.cosignproject.cosign/signature
Signature []byte // raw signature payload data
PublicKey string // PEM encoded public key associated with signature (Verify)
PublicKeyFingerPrint digest.Digest `gorm:"index"` // the digest of the public key
Annotations []SignatureAnnotation // extra data, such as verify api, userid, etc.
// Trusted is used in the code but not saved in the database.
Trusted func(TrustAnchor) bool `gorm:"-"` // true if the signature identity can be validated against a given trust anchor (fingerprint+id known)
}
Signature is used to record "signed-off" attributes for a bottle.
type SignatureAnnotation ¶
type SignatureAnnotation struct {
Model
SignatureID uint
Key string // unique per bottle
Value string
}
SignatureAnnotation is used to record extra data on a signature, such as verify api, userid, etc.
type SignatureProcessor ¶
type SignatureProcessor struct{}
SignatureProcessor handles bottle processing.
func (*SignatureProcessor) PrimaryTable ¶
func (p *SignatureProcessor) PrimaryTable() string
PrimaryTable returns primary table that this processor updates.
func (*SignatureProcessor) Process ¶
func (p *SignatureProcessor) Process(con *gorm.DB, base Base) error
Process converts Signature data to the DB model.
func (*SignatureProcessor) Version ¶
func (p *SignatureProcessor) Version() uint
Version returns the processor version.
type Source ¶
type Source struct {
BottleMemberLocated
Name string `gorm:"index"`
URI string `gorm:"index"`
// optional if the URL is a bottle
BottleDigest digest.Digest `gorm:"index"` // we do not guarantee this exists in the telemetry server so this is just a string, not a DataID, DigestID, or BottleID
// PartSelectors are used in the code but not saved in the database. They are derived from the URI query parameters
PartSelectors selectors.LabelSelectorSet `gorm:"-"`
}
Source is a data source for the bottle.
type TrustAnchor ¶
type TrustAnchor interface {
VerifyTrust() bool
}
TrustAnchor is a source which we can validate an signature owner's identity against.
type UnknownBottleRelative ¶
type UnknownBottleRelative struct {
Digest digest.Digest
PartSelectors selectors.LabelSelectorSet
}
UnknownBottleRelative represents a bottle that is not known to the telemetry server (so we know nothing more than its digest).
func (UnknownBottleRelative) MatchesSource ¶
func (b UnknownBottleRelative) MatchesSource(source Source) bool
MatchesSource returns true if the source matches this relative.