Raw
 1package configsrc
 2
 3import (
 4	"context"
 5	"fmt"
 6	"os"
 7	"time"
 8
 9	"github.com/go-git/go-git/v5/plumbing"
10	"github.com/go-git/go-git/v5/plumbing/object"
11	"golang.org/x/crypto/ssh"
12
13	"tug/internal/platform/replica"
14)
15
16type CheckpointHead struct {
17	Commit string
18	Time   time.Time
19	Signer ssh.PublicKey
20}
21
22func InspectCheckpoint(ctx context.Context, stateDir string, in Input) (CheckpointHead, error) {
23	var result CheckpointHead
24	checkpoint, err := commitID(in.Checkpoint, false)
25	if err != nil || checkpoint.IsZero() {
26		return result, fmt.Errorf("no checkpoint is set; a first start needs no reset")
27	}
28	dir, err := os.MkdirTemp(stateDir, "config-checkpoint-")
29	if err != nil {
30		return result, err
31	}
32	defer os.RemoveAll(dir)
33	s := &Source{dir: dir}
34	auth, err := s.auth(in)
35	if err != nil {
36		return result, err
37	}
38	repo, err := s.repo()
39	if err != nil {
40		return result, err
41	}
42	head, err := replica.Fetch(ctx, repo, in.Remote.URL, auth, plumbing.ReferenceName("refs/heads/"+in.Remote.Branch))
43	if err != nil {
44		return result, fmt.Errorf("unreachable: %w", err)
45	}
46	if head.IsZero() {
47		return result, errEmpty
48	}
49	key, refused, err := verify(repo.Storer, head, in.Signers)
50	if err != nil {
51		return result, err
52	}
53	if refused != nil {
54		return result, fmt.Errorf("%s: %w", refused.kind, refused.cause)
55	}
56	found, err := walk(repo.Storer, head, checkpoint)
57	if err != nil {
58		return result, err
59	}
60	if found {
61		return result, fmt.Errorf("the branch still holds the checkpoint; an ordinary start repairs the clone")
62	}
63	commit, err := object.GetCommit(repo.Storer, head)
64	if err != nil {
65		return result, err
66	}
67	return CheckpointHead{Commit: head.String(), Time: commit.Committer.When, Signer: key}, nil
68}