mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-08-29 04:06:58 +00:00
69 lines
2.1 KiB
Go
69 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"atcr.io/pkg/hold"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var scanBackfillConfigFile string
|
|
|
|
var scanBackfillCmd = &cobra.Command{
|
|
Use: "scan-backfill",
|
|
Short: "Rewrite legacy scan records to use the status field (offline)",
|
|
Long: `Walks every io.atcr.hold.scan record on this hold and assigns a status
|
|
("skipped" or "failed") to records that pre-date the status field.
|
|
|
|
A legacy record is one with an empty status, no SBOM blob, and zero
|
|
vulnerability counts. Layer media types decide the rewrite:
|
|
|
|
- helm.chart.content / in-toto / dsse.envelope → status="skipped"
|
|
- everything else → status="failed"
|
|
|
|
The tool is idempotent and preserves each record's original scannedAt.
|
|
|
|
This subcommand opens the hold's CAR store directly, so the running hold
|
|
service must be stopped first (otherwise the embedded PDS holds an exclusive
|
|
lock). For zero-downtime backfill on a production hold, hit the admin
|
|
endpoint POST /admin/api/scan-backfill instead.`,
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
cfg, err := hold.LoadConfig(scanBackfillConfigFile)
|
|
if err != nil {
|
|
return fmt.Errorf("load config: %w", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
holdPDS, cleanup, err := openHoldPDS(ctx, cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer cleanup()
|
|
|
|
logf := func(format string, args ...any) {
|
|
fmt.Fprintf(cmd.ErrOrStderr(), " "+format+"\n", args...)
|
|
}
|
|
res, err := holdPDS.BackfillScanStatus(ctx, logf, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("backfill: %w", err)
|
|
}
|
|
|
|
out := cmd.OutOrStdout()
|
|
fmt.Fprintf(out, "Backfill complete:\n")
|
|
fmt.Fprintf(out, " scanned: %d\n", res.Scanned)
|
|
fmt.Fprintf(out, " already-tagged: %d\n", res.AlreadyTagged)
|
|
fmt.Fprintf(out, " → skipped: %d\n", res.MarkedSkipped)
|
|
fmt.Fprintf(out, " → failed: %d\n", res.MarkedFailed)
|
|
fmt.Fprintf(out, " rewritten: %d\n", res.Rewritten)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
scanBackfillCmd.Flags().StringVarP(&scanBackfillConfigFile, "config", "c", "", "path to YAML configuration file")
|
|
rootCmd.AddCommand(scanBackfillCmd)
|
|
}
|