A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
80
fork

Configure Feed

Select the types of activity you want to include in your feed.

try and create a crew record for the hold owner

+60 -6
+16
cmd/hold/main.go
··· 48 48 log.Fatalf("Failed to initialize embedded PDS: %v", err) 49 49 } 50 50 51 + // Bootstrap PDS with hold owner as first crew member 52 + if err := holdPDS.Bootstrap(ctx, cfg.Registration.OwnerDID); err != nil { 53 + log.Fatalf("Failed to bootstrap PDS: %v", err) 54 + } 55 + 51 56 // Create blob store adapter 52 57 blobStore := pds.NewHoldServiceBlobStore(service, holdDID) 53 58 ··· 59 64 60 65 // Setup HTTP routes 61 66 mux := http.NewServeMux() 67 + 68 + // Root page 69 + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 70 + if r.URL.Path == "/" { 71 + w.Header().Set("Content-Type", "text/plain") 72 + fmt.Fprintf(w, "This is a hold server. More info at https://atcr.io") 73 + return 74 + } 75 + http.NotFound(w, r) 76 + }) 77 + 62 78 mux.HandleFunc("/health", service.HealthHandler) 63 79 mux.HandleFunc("/register", service.HandleRegister) 64 80 mux.HandleFunc("/presigned-url", service.HandlePresignedURL)
+19 -6
pkg/hold/pds/crew.go
··· 33 33 CrewCollection = "io.atcr.hold.crew" 34 34 ) 35 35 36 - // AddCrewMember adds a new crew member to the hold 36 + // AddCrewMember adds a new crew member to the hold and commits to carstore 37 37 func (p *HoldPDS) AddCrewMember(ctx context.Context, memberDID, role string, permissions []string) (cid.Cid, error) { 38 38 crewRecord := &CrewRecord{ 39 39 Member: memberDID, ··· 42 42 AddedAt: time.Now(), 43 43 } 44 44 45 - // Create record in repo 46 - recordCID, rkey, err := p.repo.CreateRecord(ctx, CrewCollection, crewRecord) 45 + // Create record in repo (using memberDID as rkey for easy lookup) 46 + recordCID, _, err := p.repo.CreateRecord(ctx, CrewCollection, crewRecord) 47 47 if err != nil { 48 48 return cid.Undef, fmt.Errorf("failed to create crew record: %w", err) 49 49 } 50 50 51 - // TODO: Commit the changes 52 - // For now, just return the CID 53 - _ = rkey // We'll use rkey for GetCrewMember later 51 + // Create signer function from signing key 52 + signer := func(ctx context.Context, did string, data []byte) ([]byte, error) { 53 + return p.signingKey.HashAndSign(data) 54 + } 55 + 56 + // Commit the changes to get new root CID 57 + root, rev, err := p.repo.Commit(ctx, signer) 58 + if err != nil { 59 + return cid.Undef, fmt.Errorf("failed to commit crew record: %w", err) 60 + } 61 + 62 + // Close the delta session with the new root 63 + _, err = p.session.CloseWithRoot(ctx, root, rev) 64 + if err != nil { 65 + return cid.Undef, fmt.Errorf("failed to persist commit: %w", err) 66 + } 54 67 55 68 return recordCID, nil 56 69 }
+25
pkg/hold/pds/server.go
··· 98 98 return p.signingKey 99 99 } 100 100 101 + // Bootstrap initializes the hold with the owner as the first crew member 102 + func (p *HoldPDS) Bootstrap(ctx context.Context, ownerDID string) error { 103 + if ownerDID == "" { 104 + // No owner specified, skip bootstrap 105 + return nil 106 + } 107 + 108 + // Check if repo already has commits 109 + _, err := p.carstore.GetUserRepoHead(ctx, p.uid) 110 + if err == nil { 111 + // Repo already has commits, skip bootstrap 112 + return nil 113 + } 114 + 115 + // Add hold owner as first crew member with admin role 116 + fmt.Printf("🚀 Bootstrapping hold PDS with owner: %s\n", ownerDID) 117 + _, err = p.AddCrewMember(ctx, ownerDID, "admin", []string{"blob:read", "blob:write", "crew:admin"}) 118 + if err != nil { 119 + return fmt.Errorf("failed to add owner as crew member: %w", err) 120 + } 121 + 122 + fmt.Printf("✅ Added %s as hold admin\n", ownerDID) 123 + return nil 124 + } 125 + 101 126 // Close closes the session and carstore 102 127 func (p *HoldPDS) Close() error { 103 128 // TODO: Close session properly