feat: deb (Debian/apt) local and remote repository support
Adds a deb provider with feature parity to rpm for local and remote repos, so .deb packages can be hosted (flat apt repo generated on upload) and a Debian/Ubuntu mirror can be cached through the proxy. - add PackageDeb to the package-type enum - new internal/provider/deb: Classify (.deb immutable, Packages/Release/dists mutable), ValidateUpload to pool/<file>, pure-Go .deb parse (ar -> control.tar gz/xz/zst -> ./control), and a flat-repo LocalIndexer serving Packages, Packages.gz and an unsigned Release ([trusted=yes], mirroring rpm gpgcheck=0) - remote proxy path: UpstreamURL/ContentType/AuthHeaders via BasicHeaders - DebMetadata struct + store interfaces on provider; deb_metadata table in migrate() and Insert/Delete/List DB methods - blank-import the deb provider in the server - testsupport.MinimalDeb pure-Go fixture builder - unit tests (classify, control parse across gz/xz/zst, Packages/Release generation, validate) and a dockere2e TestLocalDebRepo
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package testsupport
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// MinimalDeb builds a valid-enough Debian package in pure Go (no committed
|
||||
// binary fixture, no dpkg-deb): an ar archive of debian-binary, a gzip
|
||||
// control.tar.gz carrying ./control, and an (empty) gzip data.tar.gz. It is the
|
||||
// deb analog of MinimalRPM and is parseable by the deb provider.
|
||||
func MinimalDeb(name, version, arch string) []byte {
|
||||
control := fmt.Sprintf(
|
||||
"Package: %s\nVersion: %s\nArchitecture: %s\nMaintainer: e2e <e2e@example.com>\n"+
|
||||
"Section: utils\nPriority: optional\nDescription: minimal test package\n",
|
||||
name, version, arch)
|
||||
|
||||
controlTarGz := gzipBytes(tarSingle("./control", []byte(control)))
|
||||
dataTarGz := gzipBytes(tarEmpty())
|
||||
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString("!<arch>\n")
|
||||
arWrite(&buf, "debian-binary", []byte("2.0\n"))
|
||||
arWrite(&buf, "control.tar.gz", controlTarGz)
|
||||
arWrite(&buf, "data.tar.gz", dataTarGz)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func arWrite(buf *bytes.Buffer, name string, data []byte) {
|
||||
fmt.Fprintf(buf, "%-16s%-12s%-6s%-6s%-8s%-10d`\n", name, "0", "0", "0", "100644", len(data))
|
||||
buf.Write(data)
|
||||
if len(data)%2 == 1 {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
}
|
||||
|
||||
func tarSingle(name string, data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
tw := tar.NewWriter(&buf)
|
||||
tw.WriteHeader(&tar.Header{Name: name, Mode: 0o644, Size: int64(len(data)), Typeflag: tar.TypeReg})
|
||||
tw.Write(data)
|
||||
tw.Close()
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func tarEmpty() []byte {
|
||||
var buf bytes.Buffer
|
||||
tw := tar.NewWriter(&buf)
|
||||
tw.Close()
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func gzipBytes(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
gz := gzip.NewWriter(&buf)
|
||||
gz.Write(data)
|
||||
gz.Close()
|
||||
return buf.Bytes()
|
||||
}
|
||||
Reference in New Issue
Block a user