Documentation ¶
Overview ¶
Package libeopkg provides Go-native access to `.eopkg` files, allowing ferryd to read and manipulate them without having a host-side eopkg tool.
It should also be noted that `eopkg` is implemented in Python, so calling out to the host-side tool just isn't acceptable for the performance we require. In time, `sol` will replace eopkg and it is very likely that we'll base the new `libsol` component on the C library using cgo.
Index ¶
- Variables
- func ComputeDeltaName(oldPackage, newPackage *MetaPackage) string
- func FixMissingLocalLanguage(fields *[]LocalisedField)
- func IsDeltaPossible(oldPackage, newPackage *MetaPackage) bool
- func UnxzFile(inputPath string, keepOriginal bool) error
- func UnzstdFile(inputPath string, keepOriginal bool) error
- func XzFile(inputPath string, keepOriginal bool) error
- func ZstdFile(inputPath string, keepOriginal bool) error
- type Action
- type COMAR
- type Component
- type ComponentSort
- type Components
- type Delta
- type DeltaProducer
- type Dependency
- type Distribution
- type File
- type Files
- type Group
- type GroupSort
- type Groups
- type LocalisedField
- type MetaPackage
- type Metadata
- type Package
- type PackageSet
- type Packager
- type Provides
- type Source
- type Update
Constants ¶
This section is empty.
Variables ¶
var ( // ErrMismatchedDelta is returned when the input packages should never be delta'd, // i.e. they're unrelated ErrMismatchedDelta = errors.New("Delta is not possible between the input packages") // ErrDeltaPointless is returned when it is quite literally pointless to bother making // a delta package, due to the packages having exactly the same content. ErrDeltaPointless = errors.New("File set is the same, no point in creating delta") )
var ( // ErrNotYetImplemented is a placeholder during development ErrNotYetImplemented = errors.New("Not yet implemented") // ErrEopkgCorrupted is provided when a file does not conform to eopkg spec ErrEopkgCorrupted = errors.New(".eopkg file is corrupted or invalid") )
Functions ¶
func ComputeDeltaName ¶
func ComputeDeltaName(oldPackage, newPackage *MetaPackage) string
ComputeDeltaName will determine the target name for the delta eopkg
func FixMissingLocalLanguage ¶
func FixMissingLocalLanguage(fields *[]LocalisedField)
FixMissingLocalLanguage should be used on a set of LocalisedField to restore the missing "en" that is required in the very first field set.
func IsDeltaPossible ¶
func IsDeltaPossible(oldPackage, newPackage *MetaPackage) bool
IsDeltaPossible will compare the two input packages and determine if it is possible for a delta to be considered. Note that we do not compare the distribution _name_ because Solus already had to do a rename once, and that broke delta updates. Let's not do that again. eopkg should in reality determine delta applicability based on repo origin + upgrade path, not names
func UnxzFile ¶
UnxzFile will decompress the input XZ file and leave a new file in place without the .xz suffix
func UnzstdFile ¶
UnzstdFile will decompress the input zstd file and leave a new file in place without the .zst suffix
Types ¶
type Action ¶
type Action struct { Value string `xml:",chardata"` // i.e. "systemRestart Package string `xml:"package,attr,omitempty"` // i.e. package="kernel" }
Action represents an action to take upon applying an update, such as restarting the system.
type COMAR ¶
type COMAR struct { Value string `xml:",chardata"` // Value of the COMAR name Script string `xml:"script,attr,omitempty"` // The type of script }
A COMAR script
type Component ¶
type Component struct { Name string // ID of this component, i.e. "system.base" // Translated short name LocalName []LocalisedField // Translated summary Summary []LocalisedField // Translated description Description []LocalisedField Group string // Which group this component belongs to Maintainer struct { Name string // Name of the component maintainer Email string // Contact e-mail address of component maintainer } }
A Component as seen through the eyes of XML
type ComponentSort ¶
type ComponentSort []Component
ComponentSort allows us to quickly sort our components by name
func (ComponentSort) Len ¶
func (g ComponentSort) Len() int
func (ComponentSort) Less ¶
func (g ComponentSort) Less(a, b int) bool
func (ComponentSort) Swap ¶
func (g ComponentSort) Swap(a, b int)
type Components ¶
type Components struct {
Components []Component `xml:"Components>Component"`
}
Components is a simple helper wrapper for loading from components.xml files
func NewComponents ¶
func NewComponents(xmlfile string) (*Components, error)
NewComponents will load the Components data from the XML file
type Delta ¶
type Delta struct { ReleaseFrom int `xml:"releaseFrom,attr,omitempty"` // Delta from specified release to this one PackageURI string // Relative location to the package PackageSize int64 // Actual size on disk of the .eopkg PackageHash string // Sha1sum for this package }
Delta describes a delta package that may be used for an update to save on bandwidth for the users.
Delta upgrades are determined by placing the <DeltaPackages> section into the index, with each Delta listed with a releaseFrom. If the user is currently using one of the listed releaseFrom IDs in their installation, that delta package will be selected instead of the full package.
type DeltaProducer ¶
type DeltaProducer struct {
// contains filtered or unexported fields
}
DeltaProducer is responsible for taking two eopkg packages and spitting out a delta package for them, containing only the new files.
func NewDeltaProducer ¶
func NewDeltaProducer(baseDir string, pkgOld string, pkgNew string) (*DeltaProducer, error)
NewDeltaProducer will return a new delta producer for the given input packages It is very important that the old and new packages are in the correct order!
func (*DeltaProducer) Commit ¶
func (d *DeltaProducer) Commit() (string, error)
Commit will attempt to produce a delta between the 2 eopkg files This will be performed in temporary storage so must then be copied into the final resting location, and unlinked, before it can be used.
type Dependency ¶
type Dependency struct { Name string `xml:",chardata"` // Value of the dependency // Release based dependencies ReleaseFrom int `xml:"releaseFrom,attr,omitempty"` // >= release ReleaseTo int `xml:"releaseTo,attr,omitempty"` // <= release Release int `xml:"release,attr,omitempty"` // == release // Version based dependencies VersionFrom string `xml:"versionFrom,attr,omitempty"` // >= version VersionTo string `xml:"versionTo,attr,omitempty"` // <= version Version string `xml:"version,attr,omitempty"` // == version }
A Dependency has various attributes which help determine what needs to be installed when updating or installing the package.
type Distribution ¶
type Distribution struct { SourceName string // Name of source to match source repos // Translated description Description []struct { Value string `xml:",cdata"` Lang string `xml:"lang,attr,omitempty"` } Version string // Published version number for compatibility Type string // Type of repository (should always be main, really. Just descriptive) BinaryName string // Name of the binary repository Obsoletes []string `xml:"Obsoletes>Package"` // Package names that are no longer supported // contains filtered or unexported fields }
A Distribution as seen through the eyes of XML
func NewDistribution ¶
func NewDistribution(xmlfile string) (*Distribution, error)
NewDistribution will load the Distribution data from the XML file
func (*Distribution) IsObsolete ¶
func (d *Distribution) IsObsolete(id string) bool
IsObsolete will allow quickly determination of whether the package name was marked obsolete and should be hidden from the index
type File ¶
type File struct { Path string Type string Size int64 `xml:"Size,omitempty"` UID int `xml:"Uid,omitempty"` GID int `xml:"Gid,omitempty"` Mode string `xml:"Mode,omitempty"` Hash string `xml:"Hash,omitempty"` Permanent string `xml:"Permanent,omitempty"` // contains filtered or unexported fields }
File is the idoimatic representation of the XML <File> node
Note that directories are indicated by a missing hash. Unfortunately however eopkg doesn't record the actual _type_ of a file in an intelligent sense, thus we'll have to deal with symlinks separately.
In an ideal world the package archive would be hash indexed with no file names or special permissions inside the archive, and we'd record all relevant metadata. This would allow a single copy, many hardlink approach to blit the files out, as well as allowing us to more accurately represent symbolic links instead of pretending they're real files.
Long story short: Wait for eopkg's successor to worry about this stuff.
type Files ¶
type Files struct {
File []*File
}
Files is the idiomatic representation of the XML <Files> node with one or more <File> children
type Group ¶
type Group struct { Name string // ID of this group, i.e. "multimedia" // Translated short name LocalName []LocalisedField Icon string // Display icon for this Group }
A Group as seen through the eyes of XML
type Groups ¶
type Groups struct {
Groups []Group `xml:"Groups>Group"`
}
Groups is a simple helper wrapper for loading from components.xml files
type LocalisedField ¶
type LocalisedField struct { Value string `xml:",cdata"` Lang string `xml:"http://www.w3.org/XML/1998/namespace lang,attr,omitempty"` }
LocalisedField is used in various parts of the eopkg metadata to provide a field value with an xml:lang attribute describing the language
type MetaPackage ¶
type MetaPackage struct { // Main details Name string // Name of this binary package // Brief description, one line, of the package functionality Summary []LocalisedField // A full fleshed description of the package Description []LocalisedField IsA string `xml:"IsA,omitempty"` // Legacy construct defining type PartOf string `xml:"PartOf,omitempty"` // Which component the package belongs to License []string // The package license(s) RuntimeDependencies *[]Dependency `xml:"RuntimeDependencies>Dependency,omitempty"` // Packages this package depends on at runtime Conflicts *[]string `xml:"Conflicts>Package,omitempty"` // Conflicts with some package Replaces *[]string `xml:"Replaces>Package,omitempty"` // Replaces the named package Provides *Provides `xml:"Provides,omitempty"` History []Update `xml:"History>Update"` // A series of updates to the package // Binary details BuildHost string // Which build server produced the package Distribution string // Identifier for the distribution, i.e. "Solus" DistributionRelease string // Name/ID if this distro release, i.e. "1" Architecture string // i.e. x86_64 InstalledSize int64 // How much disk space this package takes up PackageSize int64 // Actual size on disk of the .eopkg PackageHash string // Sha1sum for this package PackageURI string // Relative location to the package // DeltaPackages are only emitted in the index itself DeltaPackages *[]Delta `xml:"DeltaPackages>Delta,omitempty"` PackageFormat string // Locked to 1.2 for eopkg // Index needs this, so do we for source==release matching Source Source // Duplicate source to satisfy indexing }
A MetaPackage is the Package section of the metadata file. It contains the main details that are important to users.
func (*MetaPackage) GetID ¶
func (m *MetaPackage) GetID() string
GetID will return the package ID for ferryd
func (*MetaPackage) GetPathComponent ¶
func (m *MetaPackage) GetPathComponent() string
GetPathComponent will get the source part of the string which is used in all subdirectories of the repository.
For all packages with a source name of 4 or more characters, the path component will be split on this, i.e.:
libr/libreoffice
For all other packages, the first letter of the source name is used, i.e.:
n/nano
func (*MetaPackage) GetRelease ¶
func (m *MetaPackage) GetRelease() int
GetRelease is a helpful wrapper to return the package's current release
func (*MetaPackage) GetVersion ¶
func (m *MetaPackage) GetVersion() string
GetVersion is a helpful wrapper to return the package's current version
type Metadata ¶
type Metadata struct { Source Source // Source of this package Package MetaPackage `xml:"Package"` // Meta on the package itself }
Metadata contains all of the information a package can provide to a user prior to installation. This includes the name, version, release, and so forth.
Every Package contains Metadata, and during eopkg indexing, a reduced version of the Metadata is emitted.
type Package ¶
type Package struct { Path string // Path to this .eopkg file ID string // Basename of the package, unique. Meta *Metadata // Metadata for this package Files *Files // Files for this package // contains filtered or unexported fields }
A Package is used for accessing a `.eopkg` archive, the current format used within Solus for software packages.
An .eopkg archive is actually a ZIP archive. Internally it has the following structure:
metadata.xml -> Package information files.xml -> Record of the files and hash/uid/gid/etc comar/ -> Postinstall scripts install.tar.xz -> Filesystem contents
Due to this toplevel simplicity, we can use golang's native `archive/zip` library to achieve eopkg access, and parse the contents accordingly. This is much faster than having to call out to the host side tool, which is presently written in Python.
func Open ¶
Open will attempt to open the given .eopkg file. This must be a valid .eopkg file and this stage will assert that it is indeed a real archive.
func (*Package) ExtractTarball ¶
ExtractTarball will fully extract install.tar.xz to the destination direction + install.tar suffix
func (*Package) FindFile ¶
FindFile will search for the given name in the .zip's file headers. We do not need to worry about the issue with the Name member being the basename, as the filenames are always unique.
In the event of the file requested not being found, we return nil. The caller should then bail and indicate that the eopkg is corrupted.
func (*Package) ReadFiles ¶
ReadFiles will read the `files.xml` file within the archive and deserialize it into something accessible within the .eopkg container.
func (*Package) ReadMetadata ¶
ReadMetadata will read the `metadata.xml` file within the archive and deserialize it into something accessible within the .eopkg container.
type PackageSet ¶
type PackageSet []*MetaPackage
PackageSet provides sorting capabilities for a slice of packages
func (PackageSet) Len ¶
func (p PackageSet) Len() int
func (PackageSet) Less ¶
func (p PackageSet) Less(a, b int) bool
func (PackageSet) Swap ¶
func (p PackageSet) Swap(a, b int)
type Packager ¶
A Packager identifies the person responsible for maintaining the source package. In terms of ypkg builds, it will indicate the last person who made a change to the package, allowing a natural "blame" system to work much like git.
type Provides ¶
type Provides struct { COMAR []COMAR `xml:"COMAR,omitempty"` PkgConfig []string `xml:"PkgConfig,omitempty"` PkgConfig32 []string `xml:"PkgConfig32,omitempty"` }
Provides defines special items that might be exported by a package
type Source ¶
type Source struct { Name string // Source name Homepage string `xml:"Homepage,omitempty"` // From whence it came Packager Packager // Who is responsible for packaging this source. }
Source provides the information relating to the source package within each binary package. This source identifies one or more packages coming from the same origin, i.e they have the same *source name*.
type Update ¶
type Update struct { Release int `xml:"release,attr"` // Relno for this update Type string `xml:"type,attr,omitempty"` // i.e. security Date string // When the update was issued Version string // Version of the package at the time of this update Comment struct { Value string `xml:",cdata"` // Comment explaining the update } Name struct { Value string `xml:",cdata"` // Updater's name } Email string // Updater's email Requires *[]Action `xml:"Requires>Action,omitempty"` }
An Update forms part of a package's history, describing the version, release, etc, for each release of the package.