311 lines
7.2 KiB
Go
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
|
|
}
|