cea107d4b5
Part of #117. The two no-affinity replicas (and every regeneration) must serve byte-identical local repodata so apt/apk never hit a checksum mismatch between an index's advertised hash and the bytes actually served. - Derive the deb Release Date: from the newest persisted created_at (RFC1123Z, UTC) instead of time.Now(); carry created_at through the deb metadata SELECT and DebMetadata struct. - Pin the apk APKINDEX tar header ModTime to the Unix epoch instead of the zero-value time.Time, so it is never wall-clock derived. - Give both list queries a genuine total order by adding a file_path tiebreak (name/version/arch is not unique). - Add guard tests: deb generators byte-identical across generations, the Release checksum/size invariant matches the served Packages(.gz) bytes, the Date: is pinned to created_at; apk index byte-identical and tar ModTime pinned to epoch.
58 lines
1.6 KiB
Go
58 lines
1.6 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, created_at
|
|
FROM deb_metadata
|
|
WHERE repo_name = $1
|
|
ORDER BY name, version, architecture, file_path
|
|
`, 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, &m.CreatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
result = append(result, m)
|
|
}
|
|
return result, rows.Err()
|
|
}
|