Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var Cmd = &cobra.Command{ Use: "check [space] [source-path-or-name]", Short: "Check upload integrity and completeness", Long: wordwrap.WrapString(`Checks uploads for data inconsistencies and incompleteness that may have occurred due to interrupted uploads or shutdowns. Performs the following checks: 1. Upload Scanned Check - Verifies FS and DAG scans completed 2. File System Integrity Check - Validates FS structure and DAG integrity 3. Node Integrity Check - Ensures all nodes have upload records 4. Node Completeness Check - Verifies all nodes are in shards 5. Shard Completeness Check - Verifies all shards are uploaded and indexed 6. Index Completeness Check - Verifies all indexes are uploaded By default, runs in dry-run mode (reports issues without fixing). Use --repair to automatically fix issues where possible. If no arguments are provided, checks all uploads. Specify a space to check only uploads for that space. Specify both space and source to check a specific upload.`, 80), Args: cobra.MaximumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() cfg, err := config.Load[config.Config]() if err != nil { return err } repo, err := preparation.OpenRepo(ctx, cfg.Repo) if err != nil { return err } defer repo.Close() client := cmdutil.MustGetClient(cfg.Repo.Dir, cfg.Network) // Determine which uploads to check var uploadsToCheck []uploadInfo switch len(args) { case 0: uploadsToCheck, err = getAllUploads(ctx, repo) if err != nil { return fmt.Errorf("getting all uploads: %w", err) } if len(uploadsToCheck) == 0 { cmd.Println("No uploads found.") return nil } cmd.Printf("Checking %d upload(s)...\n", len(uploadsToCheck)) case 1: spaceArg := args[0] spaceDID, err := cmdutil.ResolveSpace(client, spaceArg) if err != nil { return err } uploadsToCheck, err = getUploadsForSpace(ctx, repo, spaceDID) if err != nil { return fmt.Errorf("getting uploads for space %s: %w", spaceDID, err) } if len(uploadsToCheck) == 0 { cmd.Printf("No uploads found for space %s.\n", spaceDID) return nil } cmd.Printf("Checking %d upload(s) for space %s...\n", len(uploadsToCheck), spaceDID) case 2: spaceArg := args[0] sourceArg := args[1] spaceDID, err := cmdutil.ResolveSpace(client, spaceArg) if err != nil { return err } upload, err := getUploadForSpaceAndSource(ctx, repo, spaceDID, sourceArg) if err != nil { return fmt.Errorf("getting upload for space %s and source %s: %w", spaceDID, sourceArg, err) } uploadsToCheck = []uploadInfo{upload} cmd.Printf("Checking upload for space %s, source %s...\n", spaceDID, sourceArg) } sourcesAPI := sources.API{ Repo: repo, GetLocalFSForPathFn: func(path string) (fs.FS, error) { absPath, err := filepath.Abs(path) if err != nil { return nil, fmt.Errorf("resolving absolute path: %w", err) } info, err := os.Stat(absPath) if err != nil { return nil, fmt.Errorf("statting path: %w", err) } if info.IsDir() { return os.DirFS(absPath), nil } dir := filepath.Dir(absPath) base := filepath.Base(absPath) fsys, err := fs.Sub(os.DirFS(dir), base) if err != nil { return nil, fmt.Errorf("getting sub fs: %w", err) } return fsys, nil }, } nodeReaderOpener, err := nodereader.NewNodeReaderOpener( repo.LinksForCID, func(ctx context.Context, sourceID id.SourceID, path string) (fs.File, error) { source, err := repo.GetSourceByID(ctx, sourceID) if err != nil { return nil, fmt.Errorf("failed to get source by ID %s: %w", sourceID, err) } fsys, err := sourcesAPI.Access(source) if err != nil { return nil, fmt.Errorf("failed to access source %s: %w", sourceID, err) } f, err := fsys.Open(path) if err != nil { return nil, fmt.Errorf("failed to open file %s in source %s: %w", path, sourceID, err) } return f, nil }, true, ) if err != nil { return fmt.Errorf("creating node reader opener: %w", err) } checker := &prepcheck.Checker{ Repo: repo, OpenNodeReader: nodeReaderOpener.OpenNodeReader, } var opts []prepcheck.Option if checkFlags.repair { opts = append(opts, prepcheck.WithRepairs()) } allPassed := true totalRepairs := 0 for i, uploadInfo := range uploadsToCheck { if len(uploadsToCheck) > 1 { cmd.Printf("\n[%d/%d] ", i+1, len(uploadsToCheck)) } cmd.Printf("Upload: %s\n", uploadInfo.displayName) report, err := checker.CheckUpload(ctx, uploadInfo.uploadID, opts...) if err != nil { return fmt.Errorf("checking upload %s: %w", uploadInfo.uploadID, err) } printReport(cmd, report) if !report.OverallPass { allPassed = false } totalRepairs += report.RepairsApplied } if len(uploadsToCheck) > 1 { cmd.Println("\n" + strings.Repeat("=", 60)) cmd.Printf("Summary: Checked %d upload(s)\n", len(uploadsToCheck)) if allPassed { cmd.Println("✓ All uploads passed all checks") } else { cmd.Println("✗ Some uploads have issues") } if totalRepairs > 0 { cmd.Printf("Applied %d repair(s)\n", totalRepairs) } } if !allPassed { return cmdutil.NewHandledCliError(fmt.Errorf("upload check failed")) } return nil }, }
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.