Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

395 commit(s) on main

update readme Keenan Nemetz · 23m ago 32290114
history blame raw 2.7 KiB
1package web
2
3// The instance repository's admin surface. It is a section of the Configuration
4// tab: the values there are read-only host configuration, and this is the one
5// repository the instance reads as data. Creating it from here means an operator
6// does not have to remember the name or the starter files.
7
8import (
9 "net/http"
10 "strings"
11 "time"
12
13 "rodent.software/vole/forge/instancerepo"
14)
15
16// instanceRepoView is the Instance repository panel on the Configuration tab.
17type instanceRepoView struct {
18 Name string
19 Enabled bool
20 Ready bool
21 Commit string
22 Err string
23 ErrAt time.Time
24 CloneURL string
25 Created bool
26}
27
28func (w *Web) instanceRepoView(r *http.Request) instanceRepoView {
29 name := ""
30 if w.Cfg != nil {
31 name = strings.TrimSpace(w.Cfg.InstanceRepo)
32 }
33 created := false
34 if r != nil {
35 created = r.URL.Query().Get("created") == "1"
36 }
37 v := instanceRepoView{
38 Name: name,
39 Enabled: name != "",
40 Created: created,
41 }
42 if w.InstanceRepo != nil {
43 _, commit, errMsg, errAt := w.InstanceRepo.Status()
44 v.Name = w.InstanceRepo.Name()
45 v.Ready = w.InstanceRepo.Ready()
46 v.Commit, v.Err, v.ErrAt = commit, errMsg, errAt
47 }
48 if w.Cfg != nil && name != "" {
49 v.CloneURL = w.sshURL(name)
50 }
51 return v
52}
53
54// CreateInstanceRepo scaffolds the configured repository. If it already exists
55// the action only reloads it, so a repository created by hand and an empty one
56// are both recoverable from the same button.
57func (w *Web) CreateInstanceRepo(rw http.ResponseWriter, r *http.Request) {
58 pr, ok := w.beginAdminPost(rw, r, maxSmallForm)
59 if !ok {
60 return
61 }
62 name := ""
63 if w.Cfg != nil {
64 name = strings.TrimSpace(w.Cfg.InstanceRepo)
65 }
66 if name == "" {
67 w.renderAdminTab(rw, r, "configuration", "Set instance_repo before creating the repository.", http.StatusBadRequest)
68 return
69 }
70 if w.Repos == nil {
71 w.serverError(rw, r, "the repository store is unavailable")
72 return
73 }
74 m, created, err := instancerepo.Ensure(w.Repos, name, pr.account.Name, pr.account.Name)
75 if err != nil {
76 w.renderAdminTab(rw, r, "configuration", err.Error(), http.StatusBadRequest)
77 return
78 }
79 if created && w.Index != nil {
80 if err := w.Index.Upsert(m); err != nil {
81 w.serverError(rw, r, "repository created but the index was not updated: "+err.Error())
82 return
83 }
84 }
85 if w.InstanceRepo != nil {
86 if err := w.InstanceRepo.Reload(); err != nil && w.Logger != nil {
87 w.Logger("instance repository reload after create: %v", err)
88 }
89 }
90 if !created {
91 http.Redirect(rw, r, "/-/admin?tab=configuration", http.StatusSeeOther)
92 return
93 }
94 w.audit("web.admin.instance.repo", pr.account.Name, name, "created")
95 http.Redirect(rw, r, "/-/admin?tab=configuration&created=1", http.StatusSeeOther)
96}
97