mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
feat(scaletest): allow scaletests to run using the host credentials (#7075)
This commit is contained in:
@ -471,7 +471,7 @@ func (r *RootCmd) scaletestCleanup() *clibase.Cmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cliui.Errorf(inv.Stderr, "Found %d scaletest users\n", len(users))
|
cliui.Errorf(inv.Stderr, "Found %d scaletest users\n", len(users))
|
||||||
if len(workspaces) != 0 {
|
if len(users) != 0 {
|
||||||
cliui.Infof(inv.Stdout, "Deleting scaletest users..."+"\n")
|
cliui.Infof(inv.Stdout, "Deleting scaletest users..."+"\n")
|
||||||
harness := harness.NewTestHarness(cleanupStrategy.toStrategy(), harness.ConcurrentExecutionStrategy{})
|
harness := harness.NewTestHarness(cleanupStrategy.toStrategy(), harness.ConcurrentExecutionStrategy{})
|
||||||
|
|
||||||
@ -535,6 +535,8 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
|
|||||||
connectInterval time.Duration
|
connectInterval time.Duration
|
||||||
connectTimeout time.Duration
|
connectTimeout time.Duration
|
||||||
|
|
||||||
|
useHostUser bool
|
||||||
|
|
||||||
tracingFlags = &scaletestTracingFlags{}
|
tracingFlags = &scaletestTracingFlags{}
|
||||||
strategy = &scaletestStrategyFlags{}
|
strategy = &scaletestStrategyFlags{}
|
||||||
cleanupStrategy = &scaletestStrategyFlags{cleanup: true}
|
cleanupStrategy = &scaletestStrategyFlags{cleanup: true}
|
||||||
@ -693,28 +695,16 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
|
|||||||
const name = "workspacebuild"
|
const name = "workspacebuild"
|
||||||
id := strconv.Itoa(i)
|
id := strconv.Itoa(i)
|
||||||
|
|
||||||
username, email, err := newScaleTestUser(id)
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("create scaletest username and email: %w", err)
|
|
||||||
}
|
|
||||||
workspaceName, err := newScaleTestWorkspace(id)
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("create scaletest workspace name: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
config := createworkspaces.Config{
|
config := createworkspaces.Config{
|
||||||
User: createworkspaces.UserConfig{
|
User: createworkspaces.UserConfig{
|
||||||
// TODO: configurable org
|
// TODO: configurable org
|
||||||
OrganizationID: me.OrganizationIDs[0],
|
OrganizationID: me.OrganizationIDs[0],
|
||||||
Username: username,
|
|
||||||
Email: email,
|
|
||||||
},
|
},
|
||||||
Workspace: workspacebuild.Config{
|
Workspace: workspacebuild.Config{
|
||||||
OrganizationID: me.OrganizationIDs[0],
|
OrganizationID: me.OrganizationIDs[0],
|
||||||
// UserID is set by the test automatically.
|
// UserID is set by the test automatically.
|
||||||
Request: codersdk.CreateWorkspaceRequest{
|
Request: codersdk.CreateWorkspaceRequest{
|
||||||
TemplateID: tpl.ID,
|
TemplateID: tpl.ID,
|
||||||
Name: workspaceName,
|
|
||||||
ParameterValues: params,
|
ParameterValues: params,
|
||||||
},
|
},
|
||||||
NoWaitForAgents: noWaitForAgents,
|
NoWaitForAgents: noWaitForAgents,
|
||||||
@ -722,6 +712,20 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
|
|||||||
NoCleanup: noCleanup,
|
NoCleanup: noCleanup,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if useHostUser {
|
||||||
|
config.User.SessionToken = client.SessionToken()
|
||||||
|
} else {
|
||||||
|
config.User.Username, config.User.Email, err = newScaleTestUser(id)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("create scaletest username and email: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Workspace.Request.Name, err = newScaleTestWorkspace(id)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("create scaletest workspace name: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if runCommand != "" {
|
if runCommand != "" {
|
||||||
config.ReconnectingPTY = &reconnectingpty.Config{
|
config.ReconnectingPTY = &reconnectingpty.Config{
|
||||||
// AgentID is set by the test automatically.
|
// AgentID is set by the test automatically.
|
||||||
@ -927,6 +931,13 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
|
|||||||
Description: "Timeout for each request to the --connect-url.",
|
Description: "Timeout for each request to the --connect-url.",
|
||||||
Value: clibase.DurationOf(&connectTimeout),
|
Value: clibase.DurationOf(&connectTimeout),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Flag: "use-host-login",
|
||||||
|
Env: "CODER_SCALETEST_USE_HOST_LOGIN",
|
||||||
|
Default: "false",
|
||||||
|
Description: "Use the use logged in on the host machine, instead of creating users.",
|
||||||
|
Value: clibase.BoolOf(&useHostUser),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
tracingFlags.attach(&cmd.Options)
|
tracingFlags.attach(&cmd.Options)
|
||||||
@ -1009,9 +1020,6 @@ func isScaleTestUser(user codersdk.User) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isScaleTestWorkspace(workspace codersdk.Workspace) bool {
|
func isScaleTestWorkspace(workspace codersdk.Workspace) bool {
|
||||||
if !strings.HasPrefix(workspace.OwnerName, "scaletest-") {
|
return strings.HasPrefix(workspace.OwnerName, "scaletest-") ||
|
||||||
return false
|
strings.HasPrefix(workspace.Name, "scaletest-")
|
||||||
}
|
|
||||||
|
|
||||||
return strings.HasPrefix(workspace.Name, "scaletest-")
|
|
||||||
}
|
}
|
||||||
|
@ -116,5 +116,8 @@ It is recommended that all rate limits are disabled on the server before running
|
|||||||
if the server is configured with the exact same tracing configuration
|
if the server is configured with the exact same tracing configuration
|
||||||
as the client.
|
as the client.
|
||||||
|
|
||||||
|
--use-host-login bool, $CODER_SCALETEST_USE_HOST_LOGIN (default: false)
|
||||||
|
Use the use logged in on the host machine, instead of creating users.
|
||||||
|
|
||||||
---
|
---
|
||||||
Run `coder --help` for a list of global options.
|
Run `coder --help` for a list of global options.
|
||||||
|
@ -490,14 +490,14 @@ func (server *Server) UpdateJob(ctx context.Context, request *proto.UpdateJobReq
|
|||||||
slog.F("stage", log.Stage),
|
slog.F("stage", log.Stage),
|
||||||
slog.F("output", log.Output))
|
slog.F("output", log.Output))
|
||||||
}
|
}
|
||||||
//nolint:gocritic // Provisionerd has specific authz rules.
|
|
||||||
logs, err := server.Database.InsertProvisionerJobLogs(dbauthz.AsProvisionerd(context.Background()), insertParams)
|
logs, err := server.Database.InsertProvisionerJobLogs(ctx, insertParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
server.Logger.Error(ctx, "failed to insert job logs", slog.F("job_id", parsedID), slog.Error(err))
|
server.Logger.Error(ctx, "failed to insert job logs", slog.F("job_id", parsedID), slog.Error(err))
|
||||||
return nil, xerrors.Errorf("insert job logs: %w", err)
|
return nil, xerrors.Errorf("insert job logs: %w", err)
|
||||||
}
|
}
|
||||||
// Publish by the lowest log ID inserted so the
|
// Publish by the lowest log ID inserted so the log stream will fetch
|
||||||
// log stream will fetch everything from that point.
|
// everything from that point.
|
||||||
lowestID := logs[0].ID
|
lowestID := logs[0].ID
|
||||||
server.Logger.Debug(ctx, "inserted job logs", slog.F("job_id", parsedID))
|
server.Logger.Debug(ctx, "inserted job logs", slog.F("job_id", parsedID))
|
||||||
data, err := json.Marshal(ProvisionerJobLogsNotifyMessage{
|
data, err := json.Marshal(ProvisionerJobLogsNotifyMessage{
|
||||||
|
@ -282,3 +282,13 @@ Enables trace exporting to Honeycomb.io using the provided API key.
|
|||||||
| Environment | <code>$CODER_SCALETEST_TRACE_PROPAGATE</code> |
|
| Environment | <code>$CODER_SCALETEST_TRACE_PROPAGATE</code> |
|
||||||
|
|
||||||
Enables trace propagation to the Coder backend, which will be used to correlate server-side spans with client-side spans. Only enable this if the server is configured with the exact same tracing configuration as the client.
|
Enables trace propagation to the Coder backend, which will be used to correlate server-side spans with client-side spans. Only enable this if the server is configured with the exact same tracing configuration as the client.
|
||||||
|
|
||||||
|
### --use-host-login
|
||||||
|
|
||||||
|
| | |
|
||||||
|
| ----------- | -------------------------------------------- |
|
||||||
|
| Type | <code>bool</code> |
|
||||||
|
| Environment | <code>$CODER_SCALETEST_USE_HOST_LOGIN</code> |
|
||||||
|
| Default | <code>false</code> |
|
||||||
|
|
||||||
|
Use the use logged in on the host machine, instead of creating users.
|
||||||
|
@ -17,6 +17,9 @@ type UserConfig struct {
|
|||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
// Email is the email of the new user.
|
// Email is the email of the new user.
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
|
// SessionToken is the session token of an already existing user. If set, no
|
||||||
|
// user will be created.
|
||||||
|
SessionToken string `json:"session_token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c UserConfig) Validate() error {
|
func (c UserConfig) Validate() error {
|
||||||
|
@ -52,6 +52,18 @@ func (r *Runner) Run(ctx context.Context, id string, logs io.Writer) error {
|
|||||||
r.client.Logger = logger
|
r.client.Logger = logger
|
||||||
r.client.LogBodies = true
|
r.client.LogBodies = true
|
||||||
|
|
||||||
|
var (
|
||||||
|
client = r.client
|
||||||
|
user codersdk.User
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if r.cfg.User.SessionToken != "" {
|
||||||
|
_, _ = fmt.Fprintln(logs, "Using existing user session token:")
|
||||||
|
user, err = client.User(ctx, "me")
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("generate random password for user: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
_, _ = fmt.Fprintln(logs, "Generating user password...")
|
_, _ = fmt.Fprintln(logs, "Generating user password...")
|
||||||
password, err := cryptorand.String(16)
|
password, err := cryptorand.String(16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,10 +71,7 @@ func (r *Runner) Run(ctx context.Context, id string, logs io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, _ = fmt.Fprintln(logs, "Creating user:")
|
_, _ = fmt.Fprintln(logs, "Creating user:")
|
||||||
_, _ = fmt.Fprintf(logs, "\tOrg ID: %s\n", r.cfg.User.OrganizationID.String())
|
|
||||||
_, _ = fmt.Fprintf(logs, "\tUsername: %s\n", r.cfg.User.Username)
|
|
||||||
_, _ = fmt.Fprintf(logs, "\tEmail: %s\n", r.cfg.User.Email)
|
|
||||||
_, _ = fmt.Fprintf(logs, "\tPassword: ****************\n")
|
|
||||||
user, err := r.client.CreateUser(ctx, codersdk.CreateUserRequest{
|
user, err := r.client.CreateUser(ctx, codersdk.CreateUserRequest{
|
||||||
OrganizationID: r.cfg.User.OrganizationID,
|
OrganizationID: r.cfg.User.OrganizationID,
|
||||||
Username: r.cfg.User.Username,
|
Username: r.cfg.User.Username,
|
||||||
@ -75,21 +84,27 @@ func (r *Runner) Run(ctx context.Context, id string, logs io.Writer) error {
|
|||||||
r.userID = user.ID
|
r.userID = user.ID
|
||||||
|
|
||||||
_, _ = fmt.Fprintln(logs, "\nLogging in as new user...")
|
_, _ = fmt.Fprintln(logs, "\nLogging in as new user...")
|
||||||
userClient := codersdk.New(r.client.URL)
|
client = codersdk.New(r.client.URL)
|
||||||
loginRes, err := userClient.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{
|
loginRes, err := client.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{
|
||||||
Email: r.cfg.User.Email,
|
Email: r.cfg.User.Email,
|
||||||
Password: password,
|
Password: password,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("login as new user: %w", err)
|
return xerrors.Errorf("login as new user: %w", err)
|
||||||
}
|
}
|
||||||
userClient.SetSessionToken(loginRes.SessionToken)
|
client.SetSessionToken(loginRes.SessionToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(logs, "\tOrg ID: %s\n", r.cfg.User.OrganizationID.String())
|
||||||
|
_, _ = fmt.Fprintf(logs, "\tUsername: %s\n", user.Username)
|
||||||
|
_, _ = fmt.Fprintf(logs, "\tEmail: %s\n", user.Email)
|
||||||
|
_, _ = fmt.Fprintf(logs, "\tPassword: ****************\n")
|
||||||
|
|
||||||
_, _ = fmt.Fprintln(logs, "\nCreating workspace...")
|
_, _ = fmt.Fprintln(logs, "\nCreating workspace...")
|
||||||
workspaceBuildConfig := r.cfg.Workspace
|
workspaceBuildConfig := r.cfg.Workspace
|
||||||
workspaceBuildConfig.OrganizationID = r.cfg.User.OrganizationID
|
workspaceBuildConfig.OrganizationID = r.cfg.User.OrganizationID
|
||||||
workspaceBuildConfig.UserID = user.ID.String()
|
workspaceBuildConfig.UserID = user.ID.String()
|
||||||
r.workspacebuildRunner = workspacebuild.NewRunner(userClient, workspaceBuildConfig)
|
r.workspacebuildRunner = workspacebuild.NewRunner(client, workspaceBuildConfig)
|
||||||
err = r.workspacebuildRunner.Run(ctx, id, logs)
|
err = r.workspacebuildRunner.Run(ctx, id, logs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("create workspace: %w", err)
|
return xerrors.Errorf("create workspace: %w", err)
|
||||||
@ -104,7 +119,7 @@ func (r *Runner) Run(ctx context.Context, id string, logs io.Writer) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get workspace ID: %w", err)
|
return xerrors.Errorf("get workspace ID: %w", err)
|
||||||
}
|
}
|
||||||
workspace, err := userClient.Workspace(ctx, workspaceID)
|
workspace, err := client.Workspace(ctx, workspaceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get workspace %q: %w", workspaceID.String(), err)
|
return xerrors.Errorf("get workspace %q: %w", workspaceID.String(), err)
|
||||||
}
|
}
|
||||||
@ -128,7 +143,7 @@ resourceLoop:
|
|||||||
reconnectingPTYConfig := *r.cfg.ReconnectingPTY
|
reconnectingPTYConfig := *r.cfg.ReconnectingPTY
|
||||||
reconnectingPTYConfig.AgentID = agent.ID
|
reconnectingPTYConfig.AgentID = agent.ID
|
||||||
|
|
||||||
reconnectingPTYRunner := reconnectingpty.NewRunner(userClient, reconnectingPTYConfig)
|
reconnectingPTYRunner := reconnectingpty.NewRunner(client, reconnectingPTYConfig)
|
||||||
err := reconnectingPTYRunner.Run(egCtx, id, logs)
|
err := reconnectingPTYRunner.Run(egCtx, id, logs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("run reconnecting pty: %w", err)
|
return xerrors.Errorf("run reconnecting pty: %w", err)
|
||||||
@ -142,7 +157,7 @@ resourceLoop:
|
|||||||
agentConnConfig := *r.cfg.AgentConn
|
agentConnConfig := *r.cfg.AgentConn
|
||||||
agentConnConfig.AgentID = agent.ID
|
agentConnConfig.AgentID = agent.ID
|
||||||
|
|
||||||
agentConnRunner := agentconn.NewRunner(userClient, agentConnConfig)
|
agentConnRunner := agentconn.NewRunner(client, agentConnConfig)
|
||||||
err := agentConnRunner.Run(egCtx, id, logs)
|
err := agentConnRunner.Run(egCtx, id, logs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("run agent connection: %w", err)
|
return xerrors.Errorf("run agent connection: %w", err)
|
||||||
|
Reference in New Issue
Block a user