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/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

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

Blame · server/web/admin_instance.go

Line attribution on main · 96 line(s)

6ce635a8
Keenan Nemetz
1d ago
1 package 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
8 import (
9 "net/http"
10 "strings"
11 "time"
12
d37d301f
Keenan Nemetz
15h ago
13 "rodent.software/vole/forge/instancerepo"
6ce635a8
Keenan Nemetz
1d ago
14 )
15
16 // instanceRepoView is the Instance repository panel on the Configuration tab.
17 type 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
28 func (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 != "" {
268b9368
Keenan Nemetz
17h ago
49 v.CloneURL = w.sshURL(name)
6ce635a8
Keenan Nemetz
1d ago
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.
57 func (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 }
a407c4af
Keenan Nemetz
22h ago
74 m, created, err := instancerepo.Ensure(w.Repos, name, pr.account.Name, pr.account.Name)
6ce635a8
Keenan Nemetz
1d ago
75 if err != nil {
3e7c5e67
Keenan Nemetz
1d ago
76 w.renderAdminTab(rw, r, "configuration", err.Error(), http.StatusBadRequest)
77 return
6ce635a8
Keenan Nemetz
1d ago
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 {
ed03b3d1
Keenan Nemetz
2h ago
91 http.Redirect(rw, r, "/-/admin?tab=configuration", http.StatusSeeOther)
6ce635a8
Keenan Nemetz
1d ago
92 return
93 }
94 w.audit("web.admin.instance.repo", pr.account.Name, name, "created")
ed03b3d1
Keenan Nemetz
2h ago
95 http.Redirect(rw, r, "/-/admin?tab=configuration&created=1", http.StatusSeeOther)
6ce635a8
Keenan Nemetz
1d ago
96 }