rpmpack

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2024 License: Apache-2.0 Imports: 18 Imported by: 9

README

rpmpack (tar2rpm) - package rpms the easy way

Disclaimer

This is not an official Google product, it is just code that happens to be owned by Google.

Overview

tar2rpm is a tool that takes a tar and outputs an rpm. rpmpack is a golang library to create rpms. Both are written in pure go, without using rpmbuild or spec files. API documentation for rpmpack can be found in GoDoc.

Installation

$ go get -u github.com/google/rpmpack/...

This will make the tar2rpm tool available in ${GOPATH}/bin, which by default means ~/go/bin.

Usage of the binary (tar2rpm)

tar2rpm takes a tar file (from stdin or a specified filename), and outputs an rpm.

Usage:
  tar2rpm [OPTION] [FILE]
Options:
  -file FILE
        write rpm to FILE instead of stdout
  -name string
        the package name
  -release string
        the rpm release
  -version string
        the package version

Usage of the library (rpmpack)

API documentation for rpmpack can be found in GoDoc.

import "github.com/google/rpmpack"
...
r, err := rpmpack.NewRPM(rpmpack.RPMMetaData{Name: "example", Version: "3"})
if err != nil {
  ...
}
r.AddFile(rpmpack.RPMFile{
    Name: "/usr/local/hello",
    Body: []byte("content of the file"),
})
if err := r.Write(w); err != nil {
  ...
}

Usage in the bazel build system (pkg_tar2rpm)

There is a working example inside example_bazel

In WORKSPACE

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
    name = "rpmpack",
    remote = "https://github.com/google/rpmpack.git",
   branch = "master",
)

# The following will load the requirements to build rpmpack
http_archive(
    name = "io_bazel_rules_go",
    sha256 = "69de5c704a05ff37862f7e0f5534d4f479418afc21806c887db544a316f3cb6b",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
        "https://github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
    ],
)

http_archive(
    name = "bazel_gazelle",
    sha256 = "62ca106be173579c0a167deb23358fdfe71ffa1e4cfdddf5582af26520f1c66f",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",
        "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz",
    ],
)

load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")

go_rules_dependencies()

go_register_toolchains(version = "1.16")

gazelle_dependencies()

load("@com_github_google_rpmpack//:deps.bzl", "rpmpack_dependencies")

rpmpack_dependencies()

In BUILD or BUILD.bazel

load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
load("@com_github_google_rpmpack//:def.bzl", "pkg_tar2rpm")

pkg_tar(
    name = "rpmtest-tar",
    srcs = [":content1.txt"],
    mode = "0644",
    ownername = "root.root",
    package_dir = "var/lib/rpmpack",
)

pkg_tar2rpm(
    name = "rpmtest",
    data = ":rpmtest-tar",
    pkg_name = "rpmtest",
    release = "3.4",
    version = "1.2",
    prein = "echo \"This is preinst\" > /tmp/preinst.txt",
)

Features

  • You put files into the rpm, so that rpm/yum will install them on a host.
  • Simple.
  • No spec files.
  • Does not build anything.
  • Does not try to auto-detect dependencies.
  • Does not try to magically deduce on which computer architecture you run.
  • Does not require any rpm database or other state, and does not use the filesystem.

Downsides

  • Is not related to the team the builds rpmlib.
  • May easily wreak havoc on rpm based systems. It is surprisingly easy to cause rpm to segfault on corrupt rpm files.
  • Many features are missing.
  • All of the artifacts are stored in memory, sometimes more than once.
  • Less backwards compatible than rpmbuild.

Philosophy

Sometimes you just want files to make it to hosts, and be managed by the package manager. rpmbuild can use a spec file, together with a specific directory layout and local database, to build/install/package your files. But you don't need all that. You want something similar to tar.

As the project progresses, we must maintain the complexity/value ratio. This includes both code complexity and interface complexity.

Disclaimer

This is not an official Google product, it is just code that happens to be owned by Google.

Documentation

Overview

Package rpmpack packs files to rpm files. It is designed to be simple to use and deploy, not requiring any filesystem access to create rpm files.

Index

Constants

View Source
const (
	SenseAny  rpmSense = 0
	SenseLess          = 1 << iota
	SenseGreater
	SenseEqual
	SenseRPMLIB rpmSense = 1 << 24
)

https://github.com/rpm-software-management/rpm/blob/ab01b5eacf9ec6a07a5d9e1991ef476a12d264fd/include/rpm/rpmds.h#L27 SenseAny (0) specifies no specific version compare SenseLess (2) specifies less then the specified version SenseGreater (4) specifies greater then the specified version SenseEqual (8) specifies equal to the specified version

Variables

View Source
var (
	// ErrWriteAfterClose is returned when a user calls Write() on a closed rpm.
	ErrWriteAfterClose = errors.New("rpm write after close")
	// ErrWrongFileOrder is returned when files are not sorted by name.
	ErrWrongFileOrder = errors.New("wrong file addition order")
)

Functions

This section is empty.

Types

type FileType

type FileType int32

FileType is the type of a file inside a RPM package.

const (
	// GenericFile is just a basic file in an RPM
	GenericFile FileType = 1 << iota >> 1
	// ConfigFile is a configuration file, and an existing file should be saved during a
	// package upgrade operation and not removed during a package removal operation.
	ConfigFile
	// DocFile is a file that contains documentation.
	DocFile
	// DoNotUseFile is reserved for future use; conforming packages may not use this flag.
	DoNotUseFile
	// MissingOkFile need not exist on the installed system.
	MissingOkFile
	// NoReplaceFile similar to the ConfigFile, this flag indicates that during an upgrade operation
	// the original file on the system should not be altered.
	NoReplaceFile
	// SpecFile is the package specification file.
	SpecFile
	// GhostFile is not actually included in the payload, but should still be considered as a part of the package.
	// For example, a log file generated by the application at run time.
	GhostFile
	// LicenceFile contains the license conditions.
	LicenceFile
	// ReadmeFile contains high level notes about the package.
	ReadmeFile
	// ExcludeFile is not a part of the package, and should not be installed.
	ExcludeFile
)

https://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/pkgformat.html#AEN27560 The RPMFile.Type tag value shall identify various characteristics of the file in the payload that it describes. It shall be an INT32 value consisting of either the value GenericFile (0) or the bitwise inclusive or of one or more of the following values. Some of these combinations may make no sense

type IndexEntry

type IndexEntry struct {
	// contains filtered or unexported fields
}

func EntryBytes

func EntryBytes(value []byte) IndexEntry

func EntryInt16

func EntryInt16(value []int16) IndexEntry

func EntryInt32

func EntryInt32(value []int32) IndexEntry

func EntryString

func EntryString(value string) IndexEntry

func EntryStringSlice

func EntryStringSlice(value []string) IndexEntry

func EntryUint16

func EntryUint16(value []uint16) IndexEntry

func EntryUint32

func EntryUint32(value []uint32) IndexEntry

type RPM

type RPM struct {
	RPMMetaData
	// contains filtered or unexported fields
}

RPM holds the state of a particular rpm file. Please use NewRPM to instantiate it.

func FromTar

func FromTar(inp io.Reader, md RPMMetaData) (*RPM, error)

FromTar reads a tar file and creates an rpm stuct.

func NewRPM

func NewRPM(m RPMMetaData) (*RPM, error)

NewRPM creates and returns a new RPM struct.

func (*RPM) AddCustomSig

func (r *RPM) AddCustomSig(tag int, e IndexEntry)

AddCustomSig adds or overwrites a signature tag value.

func (*RPM) AddCustomTag

func (r *RPM) AddCustomTag(tag int, e IndexEntry)

AddCustomTag adds or overwrites a tag value in the index.

func (*RPM) AddFile

func (r *RPM) AddFile(f RPMFile)

AddFile adds an RPMFile to an existing rpm.

func (*RPM) AddPostin

func (r *RPM) AddPostin(s string)

AddPostin adds a postin scriptlet

func (*RPM) AddPosttrans

func (r *RPM) AddPosttrans(s string)

AddPosttrans adds a posttrans scriptlet

func (*RPM) AddPostun

func (r *RPM) AddPostun(s string)

AddPostun adds a postun scriptlet

func (*RPM) AddPrein

func (r *RPM) AddPrein(s string)

AddPrein adds a prein scriptlet

func (*RPM) AddPretrans

func (r *RPM) AddPretrans(s string)

AddPretrans adds a pretrans scriptlet

func (*RPM) AddPreun

func (r *RPM) AddPreun(s string)

AddPreun adds a preun scriptlet

func (*RPM) AddVerifyScript added in v0.6.0

func (r *RPM) AddVerifyScript(s string)

AddVerifyScript adds a verifyscript scriptlet

func (*RPM) AllowListDirs

func (r *RPM) AllowListDirs(allowList map[string]bool)

AllowListDirs removes all directories which are not explicitly allowlisted.

func (*RPM) FullVersion

func (r *RPM) FullVersion() string

FullVersion properly combines version and release fields to a version string

func (*RPM) SetPGPSigner

func (r *RPM) SetPGPSigner(f func([]byte) ([]byte, error))

SetPGPSigner registers a function that will accept the header and payload as bytes, and return a signature as bytes. The function should simulate what gpg does, probably by using golang.org/x/crypto/openpgp or by forking a gpg process.

func (*RPM) Write

func (r *RPM) Write(w io.Writer) error

Write closes the rpm and writes the whole rpm to an io.Writer

type RPMFile

type RPMFile struct {
	Name  string
	Body  []byte
	Mode  uint
	Owner string
	Group string
	MTime uint32
	Type  FileType
}

RPMFile contains a particular file's entry and data.

type RPMMetaData

type RPMMetaData struct {
	Name,
	Summary,
	Description,
	Version,
	Release,
	Arch,
	OS,
	Vendor,
	URL,
	Packager,
	Group,
	Licence,
	BuildHost,
	Compressor string
	Epoch     uint32
	BuildTime time.Time
	// Prefixes is used for relocatable packages, usually with a one item
	// slice, e.g. `["/opt"]`.
	Prefixes []string
	Provides,
	Obsoletes,
	Suggests,
	Recommends,
	Requires,
	Conflicts Relations
}

RPMMetaData contains meta info about the whole package.

type Relation

type Relation struct {
	Name    string
	Version string
	Sense   rpmSense
}

Relation is the structure of rpm sense relationships

func NewRelation

func NewRelation(related string) (*Relation, error)

NewRelation parse a string into a Relation

func (*Relation) Equal

func (r *Relation) Equal(o *Relation) bool

Equal compare the equality of two relations

func (*Relation) String

func (r *Relation) String() string

String return the string representation of the Relation

type Relations

type Relations []*Relation

Relations is a slice of Relation pointers

func (*Relations) AddToIndex

func (r *Relations) AddToIndex(h *index, nameTag, versionTag, flagsTag int) error

AddToIndex add the relations to the specified category on the index

func (*Relations) Set

func (r *Relations) Set(value string) error

Set parse a string into a Relation and append it to the Relations slice if it is missing this is used by the flag package

func (*Relations) String

func (r *Relations) String() string

String return the string representation of the Relations

Directories

Path Synopsis
cmd
rpmsample
rpmsample creates an rpm file with some known files, which can be used to test rpmpack's output against other rpm implementations.
rpmsample creates an rpm file with some known files, which can be used to test rpmpack's output against other rpm implementations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL