forked from tangled.org/core
Monorepo for Tangled

appview: knot upgrade banner

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.sh>

anirudh.fi 8ab72b34 31e626df

verified
Changed files
+80 -8
appview
+28 -5
appview/knots/knots.go
··· 681 681 682 682 func (k *Knots) banner(w http.ResponseWriter, r *http.Request) { 683 683 user := k.OAuth.GetUser(r) 684 - l := k.Logger.With("handler", "removeMember") 684 + l := k.Logger.With("handler", "banner") 685 685 l = l.With("did", user.Did) 686 686 l = l.With("handle", user.Handle) 687 687 688 - registrations, err := db.GetRegistrations( 688 + allRegistrations, err := db.GetRegistrations( 689 689 k.Db, 690 690 db.FilterEq("did", user.Did), 691 - db.FilterEq("read_only", 1), 692 691 ) 693 692 if err != nil { 694 693 l.Error("non-fatal: failed to get registrations") 695 694 return 696 695 } 697 696 698 - if registrations == nil { 697 + httpClient := &http.Client{Timeout: 5 * time.Second} 698 + regs404 := []db.Registration{} 699 + for _, reg := range allRegistrations { 700 + healthURL := fmt.Sprintf("http://%s/xrpc/_health", reg.Domain) 701 + 702 + fmt.Println(healthURL) 703 + 704 + req, err := http.NewRequestWithContext(r.Context(), http.MethodGet, healthURL, nil) 705 + if err != nil { 706 + l.Error("failed to create health check request", "domain", reg.Domain, "err", err) 707 + continue 708 + } 709 + 710 + resp, err := httpClient.Do(req) 711 + if err != nil { 712 + l.Error("failed to make health check request", "domain", reg.Domain, "err", err) 713 + continue 714 + } 715 + defer resp.Body.Close() 716 + 717 + if resp.StatusCode == http.StatusNotFound { 718 + regs404 = append(regs404, reg) 719 + } 720 + } 721 + if len(regs404) == 0 { 699 722 return 700 723 } 701 724 702 725 k.Pages.KnotBanner(w, pages.KnotBannerParams{ 703 - Registrations: registrations, 726 + Registrations: regs404, 704 727 }) 705 728 }
+6 -1
appview/pages/pages.go
··· 356 356 } 357 357 358 358 func (p *Pages) KnotBanner(w io.Writer, params KnotBannerParams) error { 359 - return p.executePlain("knots/fragments/banner", w, params) 359 + return p.executePlain("knots/fragments/bannerRequiresUpgrade", w, params) 360 360 } 361 361 362 362 type KnotsParams struct { ··· 616 616 VerifiedCommits commitverify.VerifiedCommits 617 617 Languages []types.RepoLanguageDetails 618 618 Pipelines map[string]db.Pipeline 619 + NeedsKnotUpgrade bool 619 620 types.RepoIndexResponse 620 621 } 621 622 ··· 623 624 params.Active = "overview" 624 625 if params.IsEmpty { 625 626 return p.executeRepo("repo/empty", w, params) 627 + } 628 + 629 + if params.NeedsKnotUpgrade { 630 + return p.executeRepo("repo/needsUpgrade", w, params) 626 631 } 627 632 628 633 p.rctx.RepoInfo = params.RepoInfo
+1 -2
appview/pages/templates/knots/fragments/banner.html appview/pages/templates/knots/fragments/bannerReadOnly.html
··· 1 - {{ define "knots/fragments/banner" }} 1 + {{ define "knots/fragments/bannerReadOnly" }} 2 2 <div class="w-full px-6 py-2 -z-15 bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 border border-yellow-200 dark:border-yellow-800 rounded-b drop-shadow-sm"> 3 3 A knot ({{range $i, $r := .Registrations}}{{if ne $i 0}}, {{end}}{{ $r.Domain }}{{ end }}) 4 4 that you administer is presently read-only. Consider upgrading this knot to ··· 6 6 <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/migrations/knot-1.7.0.md">Click to read the upgrade guide</a>. 7 7 </div> 8 8 {{ end }} 9 -
+12
appview/pages/templates/knots/fragments/bannerRequiresUpgrade.html
··· 1 + {{ define "knots/fragments/bannerRequiresUpgrade" }} 2 + <div class="prose mx-auto w-96 px-6 py-2 bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 border border-yellow-200 dark:border-yellow-800 rounded-b drop-shadow-sm"> 3 + The following knots that you administer require upgrade to be compatible with the latest version of Tangled: 4 + <ul> 5 + {{range $i, $r := .Registrations}} 6 + <li>{{ $r.Domain }}</li> 7 + {{ end }} 8 + </ul> 9 + Repositories hosted on these knots will not be accessible until upgraded. 10 + <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/migrations/knot-1.8.0.md">Click to read the upgrade guide</a>. 11 + </div> 12 + {{ end }}
+24
appview/pages/templates/repo/needsUpgrade.html
··· 1 + {{ define "title" }}{{ .RepoInfo.FullName }}{{ end }} 2 + 3 + {{ define "extrameta" }} 4 + {{ template "repo/fragments/meta" . }} 5 + {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }} 6 + {{ end }} 7 + 8 + {{ define "repoContent" }} 9 + <main> 10 + <div class="w-full h-full flex place-content-center {{ if .LoggedInUser }} bg-yellow-100 dark:bg-yellow-900 {{ end }}"> 11 + <div class="py-6 w-fit flex flex-col gap-4 text-center"> 12 + {{ if .LoggedInUser }} 13 + <p class=" text-yellow-800 dark:text-yellow-200 text-center"> 14 + Your knot needs an upgrade. This repository is currently unavailable to users. 15 + </p> 16 + {{ else }} 17 + <p class="text-gray-400 dark:text-gray-500 py-6 text-center"> 18 + The knot hosting this repository needs an upgrade. This repository is currently unavailable. 19 + </p> 20 + {{ end }} 21 + </div> 22 + </div> 23 + </main> 24 + {{ end }}
+9
appview/repo/index.go
··· 1 1 package repo 2 2 3 3 import ( 4 + "errors" 4 5 "fmt" 5 6 "log" 6 7 "net/http" ··· 46 47 Host: host, 47 48 } 48 49 50 + var needsKnotUpgrade bool 49 51 // Build index response from multiple XRPC calls 50 52 result, err := rp.buildIndexResponse(r.Context(), xrpcc, f, ref) 51 53 if err != nil { 54 + if errors.Is(err, xrpcclient.ErrXrpcUnsupported) { 55 + log.Println("failed to call XRPC repo.index", err) 56 + needsKnotUpgrade = true 57 + return 58 + } 59 + 52 60 rp.pages.Error503(w) 53 61 log.Println("failed to build index response", err) 54 62 return ··· 133 141 134 142 rp.pages.RepoIndexPage(w, pages.RepoIndexParams{ 135 143 LoggedInUser: user, 144 + NeedsKnotUpgrade: needsKnotUpgrade, 136 145 RepoInfo: repoInfo, 137 146 TagMap: tagMap, 138 147 RepoIndexResponse: *result,