This repository was archived by the owner on Sep 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathsite_reload.go
More file actions
82 lines (71 loc) · 2.9 KB
/
site_reload.go
File metadata and controls
82 lines (71 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package graphqlbackend
import (
"context"
"fmt"
"time"
"github.com/inconshreveable/log15" //nolint:logging // TODO move all logging to sourcegraph/log
"github.com/sourcegraph/log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8stypes "k8s.io/apimachinery/pkg/types"
"github.com/sourcegraph/sourcegraph/cmd/frontend/internal/processrestart"
"github.com/sourcegraph/sourcegraph/internal/actor"
"github.com/sourcegraph/sourcegraph/internal/audit"
"github.com/sourcegraph/sourcegraph/internal/auth"
"github.com/sourcegraph/sourcegraph/internal/cloud"
"github.com/sourcegraph/sourcegraph/internal/endpoint"
"github.com/sourcegraph/sourcegraph/internal/env"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
// canReloadSite is whether the current site can be reloaded via the API. Currently
// only goreman-managed sites can be reloaded. Callers must also check if the actor
// is an admin before actually reloading the site.
var isGoremanSite = processrestart.CanRestart()
// SRC_ENABLE_FRONTEND_SITE_RELOAD is env
var enableFrontendSiteReload = env.MustGetBool("SRC_ENABLE_FRONTEND_SITE_RELOAD", true, "Enables the /reload-site endpoint for reloading the site")
func (r *schemaResolver) ReloadSite(ctx context.Context) (*EmptyResponse, error) {
// 🚨 SECURITY: Reloading the site is an disruptive action, so only admins
// may do it.
if err := auth.CheckCurrentUserIsSiteAdmin(ctx, r.db); err != nil {
return nil, err
}
if cloud.SiteConfig().SourcegraphOperatorAuthProviderEnabled() && enableFrontendSiteReload {
// use k8s client to restart the frontend deployment rollout
client, err := endpoint.LoadClient()
if err != nil {
return nil, err
}
ns := endpoint.Namespace(r.logger)
data := fmt.Sprintf(`{"spec": {"template": {"metadata": {"annotations": {"kubectl.kubernetes.io/restartedAt": "%s", "kubernetes.io/change-cause: "frontend restart requested"}}}}}`, time.Now().Format("20060102150405"))
deploymentClient := client.AppsV1().Deployments(ns)
currentUser, err := CurrentUser(ctx, r.db)
if err != nil {
return nil, err
}
audit.Log(ctx, r.logger, audit.Record{
Entity: "GraphQL",
Action: "frontend-reload",
Fields: []log.Field{
log.String("currentUser", currentUser.user.Username),
},
})
r.logger.Info("Restarting k8s deployment")
_, err = deploymentClient.Patch(ctx, "sourcegraph-frontend",
k8stypes.StrategicMergePatchType, []byte(data), metav1.PatchOptions{})
if err != nil {
return nil, err
}
return &EmptyResponse{}, nil
}
if !isGoremanSite {
return nil, errors.New("reloading site is not supported")
}
const delay = 750 * time.Millisecond
log15.Warn("Will reload site (from API request)", "actor", actor.FromContext(ctx))
time.AfterFunc(delay, func() {
log15.Warn("Reloading site", "actor", actor.FromContext(ctx))
if err := processrestart.Restart(); err != nil {
log15.Error("Error reloading site", "err", err)
}
})
return &EmptyResponse{}, nil
}