mirror of
https://github.com/rocky-linux/peridot.git
synced 2024-09-27 14:34:09 +00:00
303 lines
9.3 KiB
Go
303 lines
9.3 KiB
Go
// Copyright (c) All respective contributors to the Peridot Project. All rights reserved.
|
|
// Copyright (c) 2021-2022 Rocky Enterprise Software Foundation, Inc. All rights reserved.
|
|
// Copyright (c) 2021-2022 Ctrl IQ, Inc. All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are met:
|
|
//
|
|
// 1. Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the name of the copyright holder nor the names of its contributors
|
|
// may be used to endorse or promote products derived from this software without
|
|
// specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
package composetools
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/gobwas/glob"
|
|
"path/filepath"
|
|
"peridot.resf.org/apollo/rpmutils"
|
|
"peridot.resf.org/peridot/yummeta"
|
|
"peridot.resf.org/utils"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidNVR = errors.New("invalid NVR")
|
|
)
|
|
|
|
var (
|
|
debugSuffixes = []string{"-debuginfo", "-debugsource"}
|
|
soGlob = glob.MustCompile("*.so.*")
|
|
gtk2EnginesGlob = glob.MustCompile("/usr/lib*/gtk-2.0/*/engines")
|
|
gtk2ModulesGlob = glob.MustCompile("/usr/lib*/gtk-2.0/*/modules")
|
|
gtk2ImmodulesGlob = glob.MustCompile("/usr/lib*/gtk-2.0/*/immodules")
|
|
gtk2LoadersGlob = glob.MustCompile("/usr/lib*/gtk-2.0/*/loaders")
|
|
gtk2PrintBackendsGlob = glob.MustCompile("/usr/lib*/gtk-2.0/*/printbackends")
|
|
gtk2FilesystemsGlob = glob.MustCompile("/usr/lib*/gtk-2.0/*/filesystems")
|
|
qtPluginsGlob = glob.MustCompile("/usr/lib*/qt*/plugins/*")
|
|
kdePluginsGlob = glob.MustCompile("/usr/lib*/kde*/plugins/*")
|
|
qt5QmlGlob = glob.MustCompile("/usr/lib*/qt5/qml/*")
|
|
gdkPixbufLoadersGlob = glob.MustCompile("/usr/lib*/gdk-pixbuf-2.0/*/loaders")
|
|
xinePluginsGlob = glob.MustCompile("/usr/lib*/xine/plugins/*")
|
|
)
|
|
|
|
func StripDebugSuffixes(name string) string {
|
|
ret := name
|
|
for _, suffix := range debugSuffixes {
|
|
ret = strings.TrimSuffix(ret, suffix)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func IsDebugPackage(name string) bool {
|
|
for _, suffix := range debugSuffixes {
|
|
if strings.HasSuffix(name, suffix) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func IsDebugPackageNvra(nvra string) (bool, error) {
|
|
if !rpmutils.NVR().MatchString(nvra) {
|
|
return false, ErrInvalidNVR
|
|
}
|
|
|
|
if rpmutils.NVRUnusualRelease().MatchString(nvra) {
|
|
match := rpmutils.NVRUnusualRelease().FindStringSubmatch(nvra)
|
|
return IsDebugPackage(match[1]), nil
|
|
}
|
|
|
|
match := rpmutils.NVR().FindStringSubmatch(nvra)
|
|
return IsDebugPackage(match[1]), nil
|
|
}
|
|
|
|
func GenNevraPrimaryPkg(pkg *yummeta.PrimaryPackage) string {
|
|
return fmt.Sprintf("%s-%s:%s-%s.%s", pkg.Name, pkg.Version.Epoch, pkg.Version.Ver, pkg.Version.Rel, pkg.Arch)
|
|
}
|
|
|
|
func MultilibMethod(pkg *yummeta.PrimaryPackage, pkgFiles []*yummeta.FilelistsFile, excludeFilter []string, includeList []string) bool {
|
|
prefer64 := []string{"gdb", "frysk", "systemtap", "systemtap-runtime", "ltrace", "strace"}
|
|
|
|
if strings.Contains(pkg.Arch, "64") {
|
|
if utils.StrContains(pkg.Name, prefer64) {
|
|
return true
|
|
}
|
|
if strings.HasPrefix(pkg.Name, "kernel") {
|
|
for _, prov := range pkg.Format.RpmProvides.RpmEntries {
|
|
if prov.Name == "kernel" || prov.Name == "kernel-devel" {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// RuntimeMultilib returns if a given package should be multilib tested by runtime rules (contains *.so)
|
|
// Ported from https://pagure.io/releng/python-multilib/blob/master/f/multilib/multilib.py#_117
|
|
func RuntimeMultilib(pkg *yummeta.PrimaryPackage, pkgFiles []*yummeta.FilelistsFile, excludeFilter []string, includeList []string) (bool, error) {
|
|
rootLibDirs := []string{"/lib", "/lib64"}
|
|
usrLibDirs := []string{"/usr/lib", "/usr/lib64"}
|
|
libDirs := append(rootLibDirs, usrLibDirs...)
|
|
oprofileLibDirs := []string{"/usr/lib/oprofile", "/usr/lib64/oprofile"}
|
|
wineDirs := []string{"/usr/lib/wine", "/usr/lib64/wine"}
|
|
saneDirs := []string{"/usr/lib/sane", "/usr/lib64/sane"}
|
|
|
|
byDir := []string{"/etc/lsb-release.d"}
|
|
extraPkgs := []string{"alsa-lib", "dri", "gtk-2.0/modules", "gtk-2.0/immodules", "krb5/plugins", "sasl2", "vdpau"}
|
|
|
|
for _, p := range extraPkgs {
|
|
byDir = append(byDir, filepath.Join("/usr/lib/", p))
|
|
byDir = append(byDir, filepath.Join("/usr/lib64/", p))
|
|
}
|
|
for _, p := range rootLibDirs {
|
|
byDir = append(byDir, filepath.Join(p, "security"))
|
|
}
|
|
|
|
// If excluded, return false
|
|
for _, filter := range excludeFilter {
|
|
g, err := glob.Compile(filter)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if g.Match(pkg.Name) {
|
|
return false, nil
|
|
}
|
|
}
|
|
// If forcefully included, return true
|
|
if utils.StrContains(pkg.Name, includeList) {
|
|
return true, nil
|
|
}
|
|
if MultilibMethod(pkg, pkgFiles, excludeFilter, includeList) {
|
|
return true, nil
|
|
}
|
|
if strings.HasPrefix(pkg.Name, "kernel") {
|
|
for _, prov := range pkg.Format.RpmProvides.RpmEntries {
|
|
if prov.Name == "kernel" {
|
|
return false, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, file := range pkgFiles {
|
|
dirName := filepath.Dir(file.Value)
|
|
fileName := filepath.Base(file.Value)
|
|
|
|
// If *.so file in LIBDIRS, return true
|
|
if utils.StrContains(dirName, libDirs) && soGlob.Match(fileName) {
|
|
return true, nil
|
|
}
|
|
if utils.StrContains(dirName, byDir) {
|
|
return true, nil
|
|
}
|
|
if dirName == "/etc/ld.so.conf.d" && strings.HasSuffix(fileName, ".conf") {
|
|
return true, nil
|
|
}
|
|
if utils.StrContains(dirName, rootLibDirs) && (strings.HasPrefix(fileName, "libnss_") || strings.HasPrefix(fileName, "libdb-")) {
|
|
return true, nil
|
|
}
|
|
|
|
// Rest of the checks here is for usrLibDirs, skip if it doesn't start with usrLibDirs
|
|
startsWithUsrLibDirs := false
|
|
for _, usrLibDir := range usrLibDirs {
|
|
if strings.HasPrefix(dirName, usrLibDir) {
|
|
startsWithUsrLibDirs = true
|
|
break
|
|
}
|
|
}
|
|
if !startsWithUsrLibDirs {
|
|
continue
|
|
}
|
|
|
|
if strings.HasPrefix(dirName, "/usr/lib/gtk-2.0") || strings.HasPrefix(dirName, "/usr/lib64/gtk-2.0") {
|
|
if gtk2EnginesGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
if gtk2ModulesGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
if gtk2ImmodulesGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
if gtk2LoadersGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
if gtk2PrintBackendsGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
if gtk2FilesystemsGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
|
|
// If none-matches, continue
|
|
continue
|
|
}
|
|
|
|
// gstreamer
|
|
if strings.HasPrefix(dirName, "/usr/lib/gstreamer-") || strings.HasPrefix(dirName, "/usr/lib64/gstreamer-") {
|
|
return true, nil
|
|
}
|
|
// qt/kde
|
|
if qtPluginsGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
if kdePluginsGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
// qml
|
|
if qt5QmlGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
if gdkPixbufLoadersGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
if xinePluginsGlob.Match(dirName) {
|
|
return true, nil
|
|
}
|
|
|
|
if utils.StrContains(dirName, oprofileLibDirs) && soGlob.Match(fileName) {
|
|
return true, nil
|
|
}
|
|
if utils.StrContains(dirName, wineDirs) && strings.HasSuffix(fileName, ".so") {
|
|
return true, nil
|
|
}
|
|
if utils.StrContains(dirName, saneDirs) && strings.HasPrefix(fileName, "libsane-") {
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
func DevelMultilib(pkg *yummeta.PrimaryPackage, pkgFiles []*yummeta.FilelistsFile, excludeFilter []string, includeList []string) (bool, error) {
|
|
// If excluded, return false
|
|
for _, filter := range excludeFilter {
|
|
g, err := glob.Compile(filter)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if g.Match(pkg.Name) {
|
|
return false, nil
|
|
}
|
|
}
|
|
if utils.StrContains(pkg.Name, excludeFilter) {
|
|
return false, nil
|
|
}
|
|
// If forcefully included, return true
|
|
if utils.StrContains(pkg.Name, includeList) {
|
|
return true, nil
|
|
}
|
|
// If allowed in RuntimeMultilib, return true
|
|
runtimeOk, err := RuntimeMultilib(pkg, pkgFiles, excludeFilter, includeList)
|
|
if err != nil {
|
|
return false, nil
|
|
}
|
|
if runtimeOk {
|
|
return true, nil
|
|
}
|
|
if strings.HasPrefix(pkg.Name, "ghc-") {
|
|
return false, nil
|
|
}
|
|
if strings.HasPrefix(pkg.Name, "kernel") {
|
|
for _, prov := range pkg.Format.RpmProvides.RpmEntries {
|
|
if prov.Name == "kernel-devel" {
|
|
return false, nil
|
|
}
|
|
if strings.HasSuffix(prov.Name, "-devel") || strings.HasSuffix(prov.Name, "-static") {
|
|
return true, nil
|
|
}
|
|
}
|
|
}
|
|
if strings.HasSuffix(pkg.Name, "-devel") {
|
|
return true, nil
|
|
}
|
|
if strings.HasSuffix(pkg.Name, "-static") {
|
|
return true, nil
|
|
}
|
|
|
|
return false, nil
|
|
}
|