diff --git a/compliance/node/index/indexer.go b/compliance/node/index/indexer.go index 521d079abde2c..9206157ffc671 100644 --- a/compliance/node/index/indexer.go +++ b/compliance/node/index/indexer.go @@ -16,6 +16,7 @@ import ( "github.com/quay/claircore" ccindexer "github.com/quay/claircore/indexer" "github.com/quay/claircore/indexer/controller" + "github.com/quay/claircore/osrelease" "github.com/quay/claircore/rhel" "github.com/quay/zlog" "github.com/rs/zerolog" @@ -190,6 +191,13 @@ func (l *localNodeIndexer) IndexNode(ctx context.Context) (*v4.IndexReport, erro return nil, errors.Wrap(err, "converting clair report to v4 report") } + dists, err := runOSScanner(ctx, layer) + if err != nil { + return nil, errors.Wrap(err, "failed to scan os-release") + } + if len(dists) > 0 { + report.Distro = mapDistribution(dists[0]) + } return report, nil } @@ -283,3 +291,30 @@ func runCoalescer(ctx context.Context, layerDigest claircore.Digest, repos []*cl return ir, nil } + +func runOSScanner(ctx context.Context, layer *claircore.Layer) ([]*claircore.Distribution, error) { + scanner := &osrelease.Scanner{} + dists, err := scanner.Scan(ctx, layer) + if err != nil { + return nil, err + } + // ID is required for the coalescer to link artifacts correctly + for i, d := range dists { + d.ID = strconv.Itoa(i) + } + return dists, nil +} + +func mapDistribution(ccDist *claircore.Distribution) *v4.Distribution { + return &v4.Distribution{ + Id: ccDist.ID, + Did: ccDist.DID, + Name: ccDist.Name, + Version: ccDist.Version, + VersionCodeName: ccDist.VersionCodeName, + VersionId: ccDist.VersionID, + Arch: ccDist.Arch, + Cpe: ccDist.CPE.BindFS(), // Converts WFN object to string + PrettyName: ccDist.PrettyName, + } +} diff --git a/generated/internalapi/scanner/v4/index_report.pb.go b/generated/internalapi/scanner/v4/index_report.pb.go index 8ef70bab7f8ec..b778e7071ecf2 100644 --- a/generated/internalapi/scanner/v4/index_report.pb.go +++ b/generated/internalapi/scanner/v4/index_report.pb.go @@ -31,6 +31,7 @@ type IndexReport struct { Success bool `protobuf:"varint,3,opt,name=success,proto3" json:"success,omitempty"` Err string `protobuf:"bytes,4,opt,name=err,proto3" json:"err,omitempty"` Contents *Contents `protobuf:"bytes,5,opt,name=contents,proto3" json:"contents,omitempty"` + Distro *Distribution `protobuf:"bytes,6,opt,name=distro,proto3" json:"distro,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -100,18 +101,26 @@ func (x *IndexReport) GetContents() *Contents { return nil } +func (x *IndexReport) GetDistro() *Distribution { + if x != nil { + return x.Distro + } + return nil +} + var File_internalapi_scanner_v4_index_report_proto protoreflect.FileDescriptor const file_internalapi_scanner_v4_index_report_proto_rawDesc = "" + "\n" + ")internalapi/scanner/v4/index_report.proto\x12\n" + - "scanner.v4\x1a#internalapi/scanner/v4/common.proto\"\x9a\x01\n" + + "scanner.v4\x1a#internalapi/scanner/v4/common.proto\"\xcc\x01\n" + "\vIndexReport\x12\x17\n" + "\ahash_id\x18\x01 \x01(\tR\x06hashId\x12\x14\n" + "\x05state\x18\x02 \x01(\tR\x05state\x12\x18\n" + "\asuccess\x18\x03 \x01(\bR\asuccess\x12\x10\n" + "\x03err\x18\x04 \x01(\tR\x03err\x120\n" + - "\bcontents\x18\x05 \x01(\v2\x14.scanner.v4.ContentsR\bcontentsB\x1dZ\x1b./internalapi/scanner/v4;v4b\x06proto3" + "\bcontents\x18\x05 \x01(\v2\x14.scanner.v4.ContentsR\bcontents\x120\n" + + "\x06distro\x18\x06 \x01(\v2\x18.scanner.v4.DistributionR\x06distroB\x1dZ\x1b./internalapi/scanner/v4;v4b\x06proto3" var ( file_internalapi_scanner_v4_index_report_proto_rawDescOnce sync.Once @@ -127,16 +136,18 @@ func file_internalapi_scanner_v4_index_report_proto_rawDescGZIP() []byte { var file_internalapi_scanner_v4_index_report_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_internalapi_scanner_v4_index_report_proto_goTypes = []any{ - (*IndexReport)(nil), // 0: scanner.v4.IndexReport - (*Contents)(nil), // 1: scanner.v4.Contents + (*IndexReport)(nil), // 0: scanner.v4.IndexReport + (*Contents)(nil), // 1: scanner.v4.Contents + (*Distribution)(nil), // 2: scanner.v4.Distribution } var file_internalapi_scanner_v4_index_report_proto_depIdxs = []int32{ 1, // 0: scanner.v4.IndexReport.contents:type_name -> scanner.v4.Contents - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 2, // 1: scanner.v4.IndexReport.distro:type_name -> scanner.v4.Distribution + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_internalapi_scanner_v4_index_report_proto_init() } diff --git a/generated/internalapi/scanner/v4/index_report_vtproto.pb.go b/generated/internalapi/scanner/v4/index_report_vtproto.pb.go index d8ece394ac279..889498724ffed 100644 --- a/generated/internalapi/scanner/v4/index_report_vtproto.pb.go +++ b/generated/internalapi/scanner/v4/index_report_vtproto.pb.go @@ -30,6 +30,7 @@ func (m *IndexReport) CloneVT() *IndexReport { r.Success = m.Success r.Err = m.Err r.Contents = m.Contents.CloneVT() + r.Distro = m.Distro.CloneVT() if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -62,6 +63,9 @@ func (this *IndexReport) EqualVT(that *IndexReport) bool { if !this.Contents.EqualVT(that.Contents) { return false } + if !this.Distro.EqualVT(that.Distro) { + return false + } return string(this.unknownFields) == string(that.unknownFields) } @@ -102,6 +106,16 @@ func (m *IndexReport) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.Distro != nil { + size, err := m.Distro.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 + } if m.Contents != nil { size, err := m.Contents.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -171,6 +185,10 @@ func (m *IndexReport) SizeVT() (n int) { l = m.Contents.SizeVT() n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + if m.Distro != nil { + l = m.Distro.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -356,6 +374,42 @@ func (m *IndexReport) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Distro", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Distro == nil { + m.Distro = &Distribution{} + } + if err := m.Distro.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -571,6 +625,42 @@ func (m *IndexReport) UnmarshalVTUnsafe(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Distro", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Distro == nil { + m.Distro = &Distribution{} + } + if err := m.Distro.UnmarshalVTUnsafe(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/proto/internalapi/scanner/v4/index_report.proto b/proto/internalapi/scanner/v4/index_report.proto index cc18584cdc2f6..c8d193e390a7d 100644 --- a/proto/internalapi/scanner/v4/index_report.proto +++ b/proto/internalapi/scanner/v4/index_report.proto @@ -15,4 +15,5 @@ message IndexReport { bool success = 3; string err = 4; Contents contents = 5; -} + Distribution distro = 6; +} \ No newline at end of file diff --git a/proto/storage/proto.lock b/proto/storage/proto.lock index a7aac75ac964b..b3249d69f0a0d 100644 --- a/proto/storage/proto.lock +++ b/proto/storage/proto.lock @@ -20361,4 +20361,4 @@ } } ] -} +} \ No newline at end of file