Files
repokit/rpm.go
2026-02-04 21:03:51 +09:00

311 lines
7.2 KiB
Go

package repokit
import "crypto/md5"
import "crypto/sha1"
import "crypto/sha256"
import "crypto/sha512"
import "encoding/hex"
import "fmt"
import "hash"
import "io"
import "os"
import "strings"
// The code for rpm repo manipulation is based on
// https://github.com/shanhai-repository/createrepo_go
// RpmChecksumType is an enumeration of supported checksum types.
// SHA is considered equivalent to SHA1 for compatibility with original createrepo.
type RpmChecksumType int
const (
RPM_CHECKSUM_UNKNOWN RpmChecksumType = iota
RPM_CHECKSUM_MD5
RPM_CHECKSUM_SHA
RPM_CHECKSUM_SHA1
RPM_CHECKSUM_SHA224
RPM_CHECKSUM_SHA256
RPM_CHECKSUM_SHA384
RPM_CHECKSUM_SHA512
RPM_CHECKSUM_SENTINEL
)
// RpmCompressionType represents the type of compression.
type RpmCompressionType int
const (
RPM_COMPRESSION_AUTO_DETECT RpmCompressionType = iota
RPM_COMPRESSION_UNKNOWN
RPM_COMPRESSION_NONE
RPM_COMPRESSION_GZ
RPM_COMPRESSION_BZ2
RPM_COMPRESSION_XZ
RPM_COMPRESSION_ZCK
RPM_COMPRESSION_ZSTD
RPM_COMPRESSION_SENTINEL
)
type RpmDepType int
const (
RPM_DEP_PROVIDES RpmDepType = iota
RPM_DEP_CONFLICTS
RPM_DEP_OBSOLETES
RPM_DEP_REQUIRES
RPM_DEP_SUGGESTS
RPM_DEP_ENHANCES
RPM_DEP_RECOMMENDS
RPM_DEP_SUPPLEMENTS
RPM_DEP_OLDSUGGESTS
RPM_DEP_OLDENHANCES
RPM_DEP_SENTINEL
)
type RpmDepItem struct {
Type RpmDepType
NameTag int
FlagsTag int
VersionTag int
}
type RpmRepomdType string
// ---------------------------------------------------------
const RpmDefaultChecksum RpmChecksumType = RPM_CHECKSUM_SHA256
const RpmDefaultRepomdChecksum RpmChecksumType = RPM_CHECKSUM_SHA256
const RpmDefaultWorkers int = 5
const RpmDefaultChangelogLimit int = 10
const RpmDefaultCompressionType RpmCompressionType = RPM_COMPRESSION_ZSTD
// extra RPMSENSE flags not defined in github.com/sassoftware/go-rpmutils
const RPM_SENSE_STRONG uint64 = 1 << 27
const RPM_SENSE_MISSINGOK uint64 = 1 << 19
// some RPM tags
const RPM_TAG_RECOMMENDNAME = 5046
const RPM_TAG_RECOMMENDVERSION = 5047
const RPM_TAG_RECOMMENDFLAGS = 5048
const RPM_TAG_SUGGESTNAME = 5049
const RPM_TAG_SUGGESTVERSION = 5050
const RPM_TAG_SUGGESTFLAGS = 5051
const RPM_TAG_SUPPLEMENTNAME = 5052
const RPM_TAG_SUPPLEMENTVERSION = 5053
const RPM_TAG_SUPPLEMENTFLAGS = 5054
const RPM_TAG_ENHANCENAME = 5055
const RPM_TAG_ENHANCEVERSION = 5056
const RPM_TAG_ENHANCEFLAGS = 5057
const RPM_XML_NS_COMMON string = "http://linux.duke.edu/metadata/common"
const RPM_XML_NS_FILELISTS string = "http://linux.duke.edu/metadata/filelists"
const RPM_XML_NS_FILELISTS_EXT string = "http://linux.duke.edu/metadata/filelists-ext"
const RPM_XML_NS_OTHER string = "http://linux.duke.edu/metadata/other"
const RPM_XML_NS_REPOMD string = "http://linux.duke.edu/metadata/repo"
const RPM_XML_NS_RPM string = "http://linux.duke.edu/metadata/rpm"
const RpmLocationHrefPrefix string = "repodata/"
const RpmRepomdTypePrimary RpmRepomdType = "primary"
const RpmRepomdTypeFilelists RpmRepomdType = "filelists"
const RpmRepomdTypeOther RpmRepomdType = "other"
const RpmRepomdTypeFilelistsExt RpmRepomdType = "filelists-ext"
// ---------------------------------------------------------
func RpmChecksumName(checksum_type RpmChecksumType) string {
var name string
switch checksum_type {
case RPM_CHECKSUM_UNKNOWN:
name = "Unknown checksum"
case RPM_CHECKSUM_MD5:
name = "md5"
case RPM_CHECKSUM_SHA:
name = "sha"
case RPM_CHECKSUM_SHA1:
name = "sha1"
case RPM_CHECKSUM_SHA224:
name = "sha224"
case RPM_CHECKSUM_SHA256:
name = "sha256"
case RPM_CHECKSUM_SHA384:
name = "sha384"
case RPM_CHECKSUM_SHA512:
name = "sha512"
default:
name = ""
}
return name
}
// ---------------------------------------------------------
func CompressionSuffix(compression_type RpmCompressionType) string {
var suffix string
switch compression_type {
case RPM_COMPRESSION_GZ:
suffix = ".gz"
case RPM_COMPRESSION_BZ2:
suffix = ".bz2"
case RPM_COMPRESSION_XZ:
suffix = ".xz"
case RPM_COMPRESSION_ZCK:
suffix = ".zck"
case RPM_COMPRESSION_ZSTD:
suffix = ".zst"
default:
suffix = ""
}
return suffix
}
// ---------------------------------------------------------
func rpm_repomd_record_type_value(record_type RpmRepomdType) int {
var value int
switch record_type {
case "primary":
value = 1
case "filelists":
value = 2
case "other":
value = 3
case "primary_db":
value = 4
case "filelists_db":
value = 5
case "other_db":
value = 6
case "primary_zck":
value = 7
case "filelists_zck":
value = 8
case "other_zck":
value = 9
default:
value = 10
}
return value
}
func rpm_repomd_record_cmp(a *RpmRepomdRecord, b *RpmRepomdRecord) int {
var a_val int
var b_val int
var ret int
a_val = rpm_repomd_record_type_value(RpmRepomdType(a.Type))
b_val = rpm_repomd_record_type_value(RpmRepomdType(b.Type))
if a_val < b_val {
return -1
}
if a_val > b_val {
return 1
}
ret = strings.Compare(a.Type, b.Type)
if ret != 0 {
return ret
}
ret = strings.Compare(a.Location.Href, b.Location.Href)
if ret != 0 {
return ret
}
return strings.Compare(a.Location.XMLBase, b.Location.XMLBase)
}
// ---------------------------------------------------------
func rpm_checksum_bytes(content []byte, checksum_type RpmChecksumType) (string, error) {
var hasher hash.Hash
var sum []byte
var checksum string
switch checksum_type {
case RPM_CHECKSUM_MD5:
hasher = md5.New()
case RPM_CHECKSUM_SHA:
hasher = sha1.New()
case RPM_CHECKSUM_SHA1:
hasher = sha1.New()
case RPM_CHECKSUM_SHA224:
hasher = sha256.New224()
case RPM_CHECKSUM_SHA256:
hasher = sha256.New()
case RPM_CHECKSUM_SHA384:
hasher = sha512.New384()
case RPM_CHECKSUM_SHA512:
hasher = sha512.New()
case RPM_CHECKSUM_UNKNOWN:
fallthrough
default:
return "", fmt.Errorf("unknown checksum type")
}
hasher.Write(content)
sum = hasher.Sum(nil)
checksum = hex.EncodeToString(sum)
return checksum, nil
}
func rpm_checksum_file(filename string, checksum_type RpmChecksumType) (string, error) {
var f *os.File
var err error
var hasher hash.Hash
var sum []byte
var checksum string
f, err = os.Open(filename)
if err != nil {
return "", err
}
defer f.Close()
switch checksum_type {
case RPM_CHECKSUM_MD5:
hasher = md5.New()
case RPM_CHECKSUM_SHA:
hasher = sha1.New()
case RPM_CHECKSUM_SHA1:
hasher = sha1.New()
case RPM_CHECKSUM_SHA224:
hasher = sha256.New224()
case RPM_CHECKSUM_SHA256:
hasher = sha256.New()
case RPM_CHECKSUM_SHA384:
hasher = sha512.New384()
case RPM_CHECKSUM_SHA512:
hasher = sha512.New()
case RPM_CHECKSUM_UNKNOWN:
fallthrough
default:
return "", fmt.Errorf("unknown checksum type")
}
_, err = io.Copy(hasher, f)
if err != nil {
return "", err
}
sum = hasher.Sum(nil)
checksum = hex.EncodeToString(sum)
return checksum, nil
}
// ---------------------------------------------------------
func rpm_init_xml_struct_all() *RpmXmlStructAll {
var result *RpmXmlStructAll
result = &RpmXmlStructAll{}
result.RpmPrimaryXMLData = RpmPrimaryXMLData{Xmlns: RPM_XML_NS_COMMON, XmlnsRPM: RPM_XML_NS_RPM}
result.RpmFilelistsXMLData = RpmFilelistsXMLData{Xmlns: RPM_XML_NS_FILELISTS}
result.RpmOtherXMLData = RpmOtherXMLData{Xmlns: RPM_XML_NS_OTHER}
result.RpmFilelistsExtXMLData = RpmFilelistsExtXMLData{Xmlns: RPM_XML_NS_FILELISTS_EXT}
return result
}