Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/dev/loadgen/cmd/run.go
2498 views
1
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package cmd
6
7
import (
8
"context"
9
"crypto/tls"
10
"crypto/x509"
11
"encoding/json"
12
"fmt"
13
"io/ioutil"
14
"os"
15
"os/signal"
16
"path"
17
"path/filepath"
18
"syscall"
19
"time"
20
21
"github.com/google/uuid"
22
log "github.com/sirupsen/logrus"
23
"github.com/spf13/cobra"
24
"google.golang.org/grpc"
25
"google.golang.org/grpc/credentials"
26
"google.golang.org/grpc/credentials/insecure"
27
"google.golang.org/protobuf/types/known/timestamppb"
28
29
csapi "github.com/gitpod-io/gitpod/content-service/api"
30
"github.com/gitpod-io/gitpod/loadgen/pkg/loadgen"
31
"github.com/gitpod-io/gitpod/loadgen/pkg/observer"
32
"github.com/gitpod-io/gitpod/ws-manager/api"
33
)
34
35
var runOpts struct {
36
TLSPath string
37
Interactive bool
38
}
39
40
// runCmd represents the run command
41
var runCmd = &cobra.Command{
42
Use: "run",
43
Short: "runs the load generator",
44
Run: func(cmd *cobra.Command, args []string) {
45
const workspaceCount = 5
46
47
var load loadgen.LoadGenerator
48
load = loadgen.NewFixedLoadGenerator(500*time.Millisecond, 300*time.Millisecond)
49
load = loadgen.NewWorkspaceCountLimitingGenerator(load, workspaceCount)
50
51
template := &api.StartWorkspaceRequest{
52
Id: "will-be-overriden",
53
Metadata: &api.WorkspaceMetadata{
54
MetaId: "will-be-overriden",
55
Owner: "00000000-0000-0000-0000-000000000000",
56
StartedAt: timestamppb.Now(),
57
},
58
ServicePrefix: "will-be-overriden",
59
Spec: &api.StartWorkspaceSpec{
60
IdeImage: &api.IDEImage{
61
WebRef: "eu.gcr.io/gitpod-core-dev/build/ide/code:commit-8c1466008dedabe79d82cbb91931a16f7ce7994c",
62
},
63
Admission: api.AdmissionLevel_ADMIT_OWNER_ONLY,
64
Git: &api.GitSpec{
65
Email: "[email protected]",
66
Username: "foobar",
67
},
68
FeatureFlags: []api.WorkspaceFeatureFlag{},
69
Initializer: &csapi.WorkspaceInitializer{
70
Spec: &csapi.WorkspaceInitializer_Git{
71
Git: &csapi.GitInitializer{
72
CheckoutLocation: "gitpod",
73
CloneTaget: "main",
74
RemoteUri: "https://github.com/gitpod-io/gitpod.git",
75
TargetMode: csapi.CloneTargetMode_REMOTE_BRANCH,
76
Config: &csapi.GitConfig{
77
Authentication: csapi.GitAuthMethod_NO_AUTH,
78
},
79
},
80
},
81
},
82
Timeout: "5m",
83
WorkspaceImage: "eu.gcr.io/gitpod-dev/workspace-images:3fcaad7ba5a5a4695782cb4c366b82f927f1e6c1cf0c88fd4f14d985f7eb21f6",
84
WorkspaceLocation: "gitpod",
85
Envvars: []*api.EnvironmentVariable{
86
{
87
Name: "THEIA_SUPERVISOR_TOKENS",
88
Value: `[{"token":"foobar","host":"gitpod-staging.com","scope":["function:getWorkspace","function:getLoggedInUser","function:getWorkspaceOwner","function:getWorkspaceUsers","function:isWorkspaceOwner","function:controlAdmission","function:setWorkspaceTimeout","function:getWorkspaceTimeout","function:sendHeartBeat","function:getOpenPorts","function:openPort","function:closePort","function:generateNewGitpodToken","function:takeSnapshot","function:stopWorkspace","resource:workspace::fa498dcc-0a84-448f-9666-79f297ad821a::get/update","resource:workspaceInstance::e0a17083-6a78-441a-9b97-ef90d6aff463::get/update/delete","resource:snapshot::*::create/get","resource:gitpodToken::*::create","resource:userStorage::*::create/get/update"],"expiryDate":"2020-12-01T07:55:12.501Z","reuse":2}]`,
89
},
90
},
91
},
92
Type: api.WorkspaceType_REGULAR,
93
}
94
95
var opts []grpc.DialOption
96
if runOpts.TLSPath != "" {
97
ca, err := ioutil.ReadFile(filepath.Join(runOpts.TLSPath, "ca.crt"))
98
if err != nil {
99
log.Fatal(err)
100
}
101
capool := x509.NewCertPool()
102
capool.AppendCertsFromPEM(ca)
103
cert, err := tls.LoadX509KeyPair(filepath.Join(runOpts.TLSPath, "tls.crt"), filepath.Join(runOpts.TLSPath, "tls.key"))
104
if err != nil {
105
log.Fatal(err)
106
}
107
creds := credentials.NewTLS(&tls.Config{
108
Certificates: []tls.Certificate{cert},
109
RootCAs: capool,
110
ServerName: "ws-manager",
111
})
112
opts = append(opts, grpc.WithTransportCredentials(creds))
113
} else {
114
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
115
}
116
117
sessionID := uuid.New().String()
118
resultsDir := fmt.Sprintf("results/run-%s", sessionID)
119
if err := os.MkdirAll(resultsDir, 0755); err != nil {
120
log.Fatal(err)
121
}
122
log.Infof("Results will be saved in dir %s", resultsDir)
123
124
conn, err := grpc.Dial("localhost:8080", opts...)
125
if err != nil {
126
log.Fatal(err)
127
}
128
defer conn.Close()
129
client := api.NewWorkspaceManagerClient(conn)
130
executor := &loadgen.WsmanExecutor{
131
C: client,
132
SessionId: sessionID,
133
}
134
135
session := &loadgen.Session{
136
Executor: executor,
137
Load: load,
138
Specs: &loadgen.FixedWorkspaceGenerator{Template: template},
139
Worker: 5,
140
Observer: []chan<- *loadgen.SessionEvent{
141
observer.NewLogObserver(true),
142
observer.NewProgressBarObserver(workspaceCount),
143
observer.NewStatsObserver(func(s *observer.Stats) {
144
fc, err := json.Marshal(s)
145
if err != nil {
146
return
147
}
148
os.WriteFile(path.Join(resultsDir, "stats.json"), fc, 0644)
149
}),
150
},
151
PostLoadWait: func() {
152
log.Info("load generation complete - press Ctrl+C to finish of")
153
<-make(chan struct{})
154
},
155
}
156
157
sctx, scancel := context.WithCancel(context.Background())
158
go func() {
159
sigc := make(chan os.Signal, 1)
160
signal.Notify(sigc, syscall.SIGINT)
161
<-sigc
162
scancel()
163
os.Exit(0)
164
}()
165
166
err = session.Run(sctx)
167
if err != nil {
168
log.WithError(err).Fatal()
169
}
170
171
},
172
}
173
174
func init() {
175
rootCmd.AddCommand(runCmd)
176
177
runCmd.Flags().StringVar(&runOpts.TLSPath, "tls", "", "path to ws-manager's TLS certificates")
178
}
179
180