60f008debc
Brings Debian/apt to artifactapi with feature parity to the existing rpm support (local + remote), so `.deb` packages can be hosted as a flat apt repo and a Debian/Ubuntu mirror can be cached through the proxy.
- Adds `deb` to the package-type enum and registers a new `internal/provider/deb` provider.
- Classifies `.deb` blobs immutable and the apt index surface (`Packages`, `Release`, `InRelease`, `dists/`, by-hash) mutable so the caching engine revalidates it.
- Parses the `.deb` in pure Go (ar archive to `control.tar.{gz,xz,zst}` to `./control`), storing the raw control stanza plus computed size/md5/sha256 as `deb_metadata`.
- Serves a flat apt repo (`deb [trusted=yes] .../ ./`): generates `Packages`, `Packages.gz` and an unsigned `Release` (returns 404 for `InRelease`/`Release.gpg`), mirroring rpm unsigned repodata / gpgcheck=0 trust model.
- Proxies a remote mirror via `UpstreamURL`/`ContentType`/`AuthHeaders` (HTTP Basic).
- Adds the `deb_metadata` table to `migrate()`, DB access methods, a `MinimalDeb` pure-Go fixture, unit tests, and a `dockere2e` `TestLocalDebRepo`.
---------
Co-authored-by: unkin-agent <unkin-agent@git.unkin.net>
Reviewed-on: #111
Co-authored-by: Unkin Agent <unkin-agent@unkin.net>
Co-committed-by: Unkin Agent <unkin-agent@unkin.net>
58 lines
1.5 KiB
Go
58 lines
1.5 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.unkin.net/unkin/artifactapi/internal/provider"
|
|
)
|
|
|
|
func (db *DB) InsertDebMetadata(ctx context.Context, meta *provider.DebMetadata) error {
|
|
_, err := db.Pool.Exec(ctx, `
|
|
INSERT INTO deb_metadata (
|
|
repo_name, file_path, content_hash,
|
|
name, version, architecture, control,
|
|
size, md5, sha256
|
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)
|
|
ON CONFLICT (repo_name, file_path) DO NOTHING
|
|
`,
|
|
meta.RepoName, meta.FilePath, meta.ContentHash,
|
|
meta.Name, meta.Version, meta.Architecture, meta.Control,
|
|
meta.Size, meta.MD5, meta.SHA256,
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (db *DB) DeleteDebMetadata(ctx context.Context, repoName, filePath string) error {
|
|
_, err := db.Pool.Exec(ctx, `DELETE FROM deb_metadata WHERE repo_name = $1 AND file_path = $2`, repoName, filePath)
|
|
return err
|
|
}
|
|
|
|
func (db *DB) ListDebMetadataEntries(ctx context.Context, repoName string) ([]provider.DebMetadata, error) {
|
|
rows, err := db.Pool.Query(ctx, `
|
|
SELECT repo_name, file_path, content_hash,
|
|
name, version, architecture, control,
|
|
size, md5, sha256
|
|
FROM deb_metadata
|
|
WHERE repo_name = $1
|
|
ORDER BY name, version, architecture
|
|
`, repoName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var result []provider.DebMetadata
|
|
for rows.Next() {
|
|
var m provider.DebMetadata
|
|
if err := rows.Scan(
|
|
&m.RepoName, &m.FilePath, &m.ContentHash,
|
|
&m.Name, &m.Version, &m.Architecture, &m.Control,
|
|
&m.Size, &m.MD5, &m.SHA256,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
result = append(result, m)
|
|
}
|
|
return result, rows.Err()
|
|
}
|