Merge pull request #738 from Allda/potentialNamespaceAncestry
Use PotentialNamespace in ancestry
This commit is contained in:
commit
098cb2ef2c
11
ancestry.go
11
ancestry.go
@ -211,11 +211,22 @@ func (b *AncestryBuilder) createLayerIndexedFeature(namespace *layerIndexedNames
|
|||||||
|
|
||||||
func (b *AncestryBuilder) lookupNamespace(feature *database.LayerFeature) (*layerIndexedNamespace, bool) {
|
func (b *AncestryBuilder) lookupNamespace(feature *database.LayerFeature) (*layerIndexedNamespace, bool) {
|
||||||
matchedNamespaces := []*layerIndexedNamespace{}
|
matchedNamespaces := []*layerIndexedNamespace{}
|
||||||
|
if feature.PotentialNamespace.Name != "" {
|
||||||
|
a := &layerIndexedNamespace{
|
||||||
|
Namespace: database.LayerNamespace{
|
||||||
|
Namespace: feature.PotentialNamespace,
|
||||||
|
},
|
||||||
|
IntroducedIn: b.layerIndex,
|
||||||
|
}
|
||||||
|
matchedNamespaces = append(matchedNamespaces, a)
|
||||||
|
} else {
|
||||||
|
|
||||||
for i, namespace := range b.namespaces {
|
for i, namespace := range b.namespaces {
|
||||||
if namespace.Namespace.VersionFormat == feature.VersionFormat {
|
if namespace.Namespace.VersionFormat == feature.VersionFormat {
|
||||||
matchedNamespaces = append(matchedNamespaces, &b.namespaces[i])
|
matchedNamespaces = append(matchedNamespaces, &b.namespaces[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(matchedNamespaces) == 1 {
|
if len(matchedNamespaces) == 1 {
|
||||||
return matchedNamespaces[0], true
|
return matchedNamespaces[0], true
|
||||||
|
@ -31,6 +31,7 @@ var (
|
|||||||
aptsources = database.NewNamespaceDetector("apt-sources", "1.0")
|
aptsources = database.NewNamespaceDetector("apt-sources", "1.0")
|
||||||
ubuntu = *database.NewNamespace("ubuntu:14.04", "dpkg")
|
ubuntu = *database.NewNamespace("ubuntu:14.04", "dpkg")
|
||||||
ubuntu16 = *database.NewNamespace("ubuntu:16.04", "dpkg")
|
ubuntu16 = *database.NewNamespace("ubuntu:16.04", "dpkg")
|
||||||
|
rhel7 = *database.NewNamespace("cpe:/o:redhat:enterprise_linux:7::computenode", "rpm")
|
||||||
debian = *database.NewNamespace("debian:7", "dpkg")
|
debian = *database.NewNamespace("debian:7", "dpkg")
|
||||||
python2 = *database.NewNamespace("python:2", "pip")
|
python2 = *database.NewNamespace("python:2", "pip")
|
||||||
sed = *database.NewSourcePackage("sed", "4.4-2", "dpkg")
|
sed = *database.NewSourcePackage("sed", "4.4-2", "dpkg")
|
||||||
@ -39,6 +40,8 @@ var (
|
|||||||
tar = *database.NewBinaryPackage("tar", "1.29b-2", "dpkg")
|
tar = *database.NewBinaryPackage("tar", "1.29b-2", "dpkg")
|
||||||
scipy = *database.NewSourcePackage("scipy", "3.0.0", "pip")
|
scipy = *database.NewSourcePackage("scipy", "3.0.0", "pip")
|
||||||
|
|
||||||
|
emptyNamespace = database.Namespace{}
|
||||||
|
|
||||||
detectors = []database.Detector{dpkg, osrelease, rpm}
|
detectors = []database.Detector{dpkg, osrelease, rpm}
|
||||||
multinamespaceDetectors = []database.Detector{dpkg, osrelease, pip}
|
multinamespaceDetectors = []database.Detector{dpkg, osrelease, pip}
|
||||||
)
|
)
|
||||||
@ -97,10 +100,11 @@ func (b *layerBuilder) addNamespace(detector database.Detector, ns database.Name
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *layerBuilder) addFeature(detector database.Detector, f database.Feature) *layerBuilder {
|
func (b *layerBuilder) addFeature(detector database.Detector, f database.Feature, ns database.Namespace) *layerBuilder {
|
||||||
b.layer.Features = append(b.layer.Features, database.LayerFeature{
|
b.layer.Features = append(b.layer.Features, database.LayerFeature{
|
||||||
Feature: f,
|
Feature: f,
|
||||||
By: detector,
|
By: detector,
|
||||||
|
PotentialNamespace: ns,
|
||||||
})
|
})
|
||||||
|
|
||||||
return b
|
return b
|
||||||
@ -112,39 +116,43 @@ var testImage = []*database.Layer{
|
|||||||
// ubuntu namespace
|
// ubuntu namespace
|
||||||
newLayerBuilder("1").addNamespace(osrelease, ubuntu).layer,
|
newLayerBuilder("1").addNamespace(osrelease, ubuntu).layer,
|
||||||
// install sed
|
// install sed
|
||||||
newLayerBuilder("2").addFeature(dpkg, sed).layer,
|
newLayerBuilder("2").addFeature(dpkg, sed, emptyNamespace).layer,
|
||||||
// install tar
|
// install tar
|
||||||
newLayerBuilder("3").addFeature(dpkg, sed).addFeature(dpkg, tar).layer,
|
newLayerBuilder("3").addFeature(dpkg, sed, emptyNamespace).addFeature(dpkg, tar, emptyNamespace).layer,
|
||||||
// remove tar
|
// remove tar
|
||||||
newLayerBuilder("4").addFeature(dpkg, sed).layer,
|
newLayerBuilder("4").addFeature(dpkg, sed, emptyNamespace).layer,
|
||||||
// upgrade ubuntu
|
// upgrade ubuntu
|
||||||
newLayerBuilder("5").addNamespace(osrelease, ubuntu16).layer,
|
newLayerBuilder("5").addNamespace(osrelease, ubuntu16).layer,
|
||||||
// no change to the detectable files
|
// no change to the detectable files
|
||||||
newLayerBuilder("6").layer,
|
newLayerBuilder("6").layer,
|
||||||
// change to the package installer database but no features are affected.
|
// change to the package installer database but no features are affected.
|
||||||
newLayerBuilder("7").addFeature(dpkg, sed).layer,
|
newLayerBuilder("7").addFeature(dpkg, sed, emptyNamespace).layer,
|
||||||
}
|
}
|
||||||
|
|
||||||
var invalidNamespace = []*database.Layer{
|
var invalidNamespace = []*database.Layer{
|
||||||
// add package without namespace, this indicates that the namespace detector
|
// add package without namespace, this indicates that the namespace detector
|
||||||
// could not detect the namespace.
|
// could not detect the namespace.
|
||||||
newLayerBuilder("0").addFeature(dpkg, sed).layer,
|
newLayerBuilder("0").addFeature(dpkg, sed, emptyNamespace).layer,
|
||||||
}
|
}
|
||||||
|
|
||||||
var noMatchingNamespace = []*database.Layer{
|
var noMatchingNamespace = []*database.Layer{
|
||||||
newLayerBuilder("0").addFeature(rpm, sedByRPM).addFeature(dpkg, sed).addNamespace(osrelease, ubuntu).layer,
|
newLayerBuilder("0").addFeature(rpm, sedByRPM, emptyNamespace).addFeature(dpkg, sed, emptyNamespace).addNamespace(osrelease, ubuntu).layer,
|
||||||
}
|
}
|
||||||
|
|
||||||
var multiplePackagesOnFirstLayer = []*database.Layer{
|
var multiplePackagesOnFirstLayer = []*database.Layer{
|
||||||
newLayerBuilder("0").addFeature(dpkg, sed).addFeature(dpkg, tar).addFeature(dpkg, sedBin).addNamespace(osrelease, ubuntu16).layer,
|
newLayerBuilder("0").addFeature(dpkg, sed, emptyNamespace).addFeature(dpkg, tar, emptyNamespace).addFeature(dpkg, sedBin, emptyNamespace).addNamespace(osrelease, ubuntu16).layer,
|
||||||
}
|
}
|
||||||
|
|
||||||
var twoNamespaceDetectorsWithSameResult = []*database.Layer{
|
var twoNamespaceDetectorsWithSameResult = []*database.Layer{
|
||||||
newLayerBuilderWithoutDetector("0").addDetectors(dpkg, aptsources, osrelease).addFeature(dpkg, sed).addNamespace(aptsources, ubuntu).addNamespace(osrelease, ubuntu).layer,
|
newLayerBuilderWithoutDetector("0").addDetectors(dpkg, aptsources, osrelease).addFeature(dpkg, sed, emptyNamespace).addNamespace(aptsources, ubuntu).addNamespace(osrelease, ubuntu).layer,
|
||||||
}
|
}
|
||||||
|
|
||||||
var sameVersionFormatDiffName = []*database.Layer{
|
var sameVersionFormatDiffName = []*database.Layer{
|
||||||
newLayerBuilder("0").addFeature(dpkg, sed).addNamespace(aptsources, ubuntu).addNamespace(osrelease, debian).layer,
|
newLayerBuilder("0").addFeature(dpkg, sed, emptyNamespace).addNamespace(aptsources, ubuntu).addNamespace(osrelease, debian).layer,
|
||||||
|
}
|
||||||
|
|
||||||
|
var potentialFeatureNamespace = []*database.Layer{
|
||||||
|
newLayerBuilder("0").addFeature(rpm, sed, rhel7).layer,
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddLayer(t *testing.T) {
|
func TestAddLayer(t *testing.T) {
|
||||||
@ -262,6 +270,10 @@ func TestAddLayer(t *testing.T) {
|
|||||||
title: "noMatchingNamespace",
|
title: "noMatchingNamespace",
|
||||||
image: noMatchingNamespace,
|
image: noMatchingNamespace,
|
||||||
expectedAncestry: *newAncestryBuilder(ancestryName([]string{"0"})).addDetectors(detectors...).addLayer("0", ancestryFeature(ubuntu, sed, osrelease, dpkg)).ancestry,
|
expectedAncestry: *newAncestryBuilder(ancestryName([]string{"0"})).addDetectors(detectors...).addLayer("0", ancestryFeature(ubuntu, sed, osrelease, dpkg)).ancestry,
|
||||||
|
}, {
|
||||||
|
title: "featureWithPotentialNamespace",
|
||||||
|
image: potentialFeatureNamespace,
|
||||||
|
expectedAncestry: *newAncestryBuilder(ancestryName([]string{"0"})).addDetectors(detectors...).addLayer("0", ancestryFeature(rhel7, sed, database.Detector{}, rpm)).ancestry,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +153,9 @@ func NamespacedFeatureFromDatabaseModel(feature database.AncestryFeature) *Featu
|
|||||||
|
|
||||||
// DetectorFromDatabaseModel converts database detector to api detector.
|
// DetectorFromDatabaseModel converts database detector to api detector.
|
||||||
func DetectorFromDatabaseModel(detector database.Detector) *Detector {
|
func DetectorFromDatabaseModel(detector database.Detector) *Detector {
|
||||||
|
if !detector.Valid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return &Detector{
|
return &Detector{
|
||||||
Name: detector.Name,
|
Name: detector.Name,
|
||||||
Version: detector.Version,
|
Version: detector.Version,
|
||||||
|
@ -50,7 +50,7 @@ func FindAncestryFeatures(tx *sql.Tx, ancestryID int64, detectors detector.Detec
|
|||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var (
|
var (
|
||||||
featureDetectorID int64
|
featureDetectorID int64
|
||||||
namespaceDetectorID int64
|
namespaceDetectorID sql.NullInt64
|
||||||
feature database.NamespacedFeature
|
feature database.NamespacedFeature
|
||||||
// index is used to determine which layer the feature belongs to.
|
// index is used to determine which layer the feature belongs to.
|
||||||
index sql.NullInt64
|
index sql.NullInt64
|
||||||
@ -81,10 +81,15 @@ func FindAncestryFeatures(tx *sql.Tx, ancestryID int64, detectors detector.Detec
|
|||||||
return nil, database.ErrInconsistent
|
return nil, database.ErrInconsistent
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDetector, ok := detectors.ByID[namespaceDetectorID]
|
var nsDetector database.Detector
|
||||||
|
if !namespaceDetectorID.Valid {
|
||||||
|
nsDetector = database.Detector{}
|
||||||
|
} else {
|
||||||
|
nsDetector, ok = detectors.ByID[namespaceDetectorID.Int64]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, database.ErrInconsistent
|
return nil, database.ErrInconsistent
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
featureMap[index.Int64] = append(featureMap[index.Int64], database.AncestryFeature{
|
featureMap[index.Int64] = append(featureMap[index.Int64], database.AncestryFeature{
|
||||||
NamespacedFeature: feature,
|
NamespacedFeature: feature,
|
||||||
@ -120,9 +125,11 @@ func InsertAncestryFeatures(tx *sql.Tx, ancestryLayerID int64, layer database.An
|
|||||||
return database.ErrMissingEntities
|
return database.ErrMissingEntities
|
||||||
}
|
}
|
||||||
|
|
||||||
namespaceDetectorID, ok := detectors.ByValue[layer.Features[index].NamespaceBy]
|
var namespaceDetectorID sql.NullInt64
|
||||||
if !ok {
|
var ok bool
|
||||||
return database.ErrMissingEntities
|
namespaceDetectorID.Int64, ok = detectors.ByValue[layer.Features[index].NamespaceBy]
|
||||||
|
if ok {
|
||||||
|
namespaceDetectorID.Valid = true
|
||||||
}
|
}
|
||||||
|
|
||||||
featureDetectorID, ok := detectors.ByValue[layer.Features[index].FeatureBy]
|
featureDetectorID, ok := detectors.ByValue[layer.Features[index].FeatureBy]
|
||||||
|
@ -127,7 +127,7 @@ var (
|
|||||||
ancestry_layer_id INT NOT NULL REFERENCES ancestry_layer ON DELETE CASCADE,
|
ancestry_layer_id INT NOT NULL REFERENCES ancestry_layer ON DELETE CASCADE,
|
||||||
namespaced_feature_id INT NOT NULL REFERENCES namespaced_feature ON DELETE CASCADE,
|
namespaced_feature_id INT NOT NULL REFERENCES namespaced_feature ON DELETE CASCADE,
|
||||||
feature_detector_id INT NOT NULL REFERENCES detector ON DELETE CASCADE,
|
feature_detector_id INT NOT NULL REFERENCES detector ON DELETE CASCADE,
|
||||||
namespace_detector_id INT NOT NULL REFERENCES detector ON DELETE CASCADE,
|
namespace_detector_id INT REFERENCES detector ON DELETE CASCADE,
|
||||||
UNIQUE (ancestry_layer_id, namespaced_feature_id));`,
|
UNIQUE (ancestry_layer_id, namespaced_feature_id));`,
|
||||||
|
|
||||||
`CREATE TABLE IF NOT EXISTS ancestry_detector(
|
`CREATE TABLE IF NOT EXISTS ancestry_detector(
|
||||||
|
Loading…
Reference in New Issue
Block a user