The failure condition being fixed is `w1` and `w2` could belong
to different users, organizations, and templates and still cause a
serializable failure if run concurrently. This is because the old query
did a `seq scan` on the `workspace_builds` table. Since that is the
table being updated, we really want to prevent that.
So before this would fail for any 2 workspaces. Now it only fails if
`w1` and `w2` are owned by the same user and organization.
Fixes#15312
When we need to `Unlisten()` for an event, instead of immediately removing the event from the `p.queues`, we store a channel to signal any goroutines trying to Subscribe to the same event when we are done. On `Subscribe`, if the channel is present, wait for it before calling `Listen` to ensure the ordering is correct.
Closes#14716Closes#14717
Adds a new user-scoped tailnet API endpoint (`api/v2/tailnet`) with a new RPC stream for receiving updates on workspaces owned by a specific user, as defined in #14716.
When a stream is started, the `WorkspaceUpdatesProvider` will begin listening on the user-scoped pubsub events implemented in #14964. When a relevant event type is seen (such as a workspace state transition), the provider will query the DB for all the workspaces (and agents) owned by the user. This gets compared against the result of the previous query to produce a set of workspace updates.
Workspace updates can be requested for any user ID, however only workspaces the authorised user is permitted to `ActionRead` will have their updates streamed.
Opening a tunnel to an agent requires that the user can perform `ActionSSH` against the workspace containing it.
Second PR for #14716.
Adds a query that, given a user ID, returns all the workspaces they own, that can also be `ActionRead` by the requesting user.
```
type GetWorkspacesAndAgentsByOwnerIDRow struct {
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
WorkspaceName string `db:"workspace_name" json:"workspace_name"`
JobStatus ProvisionerJobStatus `db:"job_status" json:"job_status"`
Transition WorkspaceTransition `db:"transition" json:"transition"`
Agents []AgentIDNamePair `db:"agents" json:"agents"`
}
```
`JobStatus` and `Transition` are set using the latest build/job of the workspace. Deleted workspaces are not included.
We currently send empty payloads to pubsub channels of the form `workspace:<workspace_id>` to notify listeners of updates to workspaces (such as for refreshing the workspace dashboard).
To support https://github.com/coder/coder/issues/14716, we'll instead send `WorkspaceEvent` payloads to pubsub channels of the form `workspace_owner:<owner_id>`. This enables a listener to receive events for all workspaces owned by a user.
This PR replaces the usage of the old channels without modifying any existing behaviors.
```
type WorkspaceEvent struct {
Kind WorkspaceEventKind `json:"kind"`
WorkspaceID uuid.UUID `json:"workspace_id" format:"uuid"`
// AgentID is only set for WorkspaceEventKindAgent* events
// (excluding AgentTimeout)
AgentID *uuid.UUID `json:"agent_id,omitempty" format:"uuid"`
}
```
We've defined `WorkspaceEventKind`s based on how the old channel was used, but it's not yet necessary to inspect the types of any of the events, as the existing listeners are designed to fire off any of them.
```
WorkspaceEventKindStateChange WorkspaceEventKind = "state_change"
WorkspaceEventKindStatsUpdate WorkspaceEventKind = "stats_update"
WorkspaceEventKindMetadataUpdate WorkspaceEventKind = "mtd_update"
WorkspaceEventKindAppHealthUpdate WorkspaceEventKind = "app_health"
WorkspaceEventKindAgentLifecycleUpdate WorkspaceEventKind = "agt_lifecycle_update"
WorkspaceEventKindAgentLogsUpdate WorkspaceEventKind = "agt_logs_update"
WorkspaceEventKindAgentConnectionUpdate WorkspaceEventKind = "agt_connection_update"
WorkspaceEventKindAgentLogsOverflow WorkspaceEventKind = "agt_logs_overflow"
WorkspaceEventKindAgentTimeout WorkspaceEventKind = "agt_timeout"
```
Closes https://github.com/coder/coder/issues/15213
This PR enables sending notifications without requiring the auth system
context, instead using a new auth notifier context.
The subquery on the users table was incorrectly using the username from
the `workspaces` table, not the `users` table.
This passed `sqlc-vet` because the column did exist in the query, it
just was not the correct one.
Part of https://github.com/coder/coder/issues/15176
I originally kept this the same because I wanted to be conservative
about when we start dropping activity, but this is proving to be a
problem when using `coder ssh` with `--usage-app=disabled`. Because the
workspace agent still counts this as a connection (I think it still
should so it's counted somewhere) but not as a SSH / IDE session. This
leads to background ssh tasks that want to be untracked still continuing
to bump activity when it shouldn't. This makes it so we have to have an
explicit session to bump activity.
Closes https://github.com/coder/coder/issues/15154
Log when someone attempts to either
- Request a one-time passcode for an account that doesn't exist
- Attempt to change a password with an invalid one-time passcode and/or
email
---------
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
Closes#15212
## Changes made
- Updated logic so that proxy config is only requested when appropriate,
instead of for all users on all deployment pages
- Split up the main context provider for the `/deployment` and
`/organizations` routes, and updated layout logic for
`ManagementSettingsLayout` layout component. This ensures the sidebar is
always visible, even if request errors happen
- Added additional routing safeguards to make sure that even if a user
can view one page in the deployment section, they won't be able to
navigate directly to any arbitrary deployment page
- Updated logic for sidebar navigation to ensure that nav items only
appear when the user truly has permission
- Centralized a lot of the orgs logic into the `useAuthenticated` hook
- Added additional check cases to the `permissions.tsx` file, to give
more granularity, and added missing type-checking
- Extended the API for the `RequirePermissions` component to let it
redirect users anywhere
- Updated some of our testing setup files to ensure that types were
defined correctly
---------
Co-authored-by: McKayla Washburn <mckayla@hey.com>
Previously, `make gen` ran on CI whenever a non-docs change was made.
Based off the problem described in #15252, it sounds like CI should
*always* be running `gen`.
(Because I broke it, currently PR `gen` is getting skipped unless the
`ci` category is updated)