refactor(coderd/database): split `Time` and `Now` into `dbtime` package (#9482)

Ref: #9380
This commit is contained in:
Mathias Fredriksson 2023-09-01 19:50:12 +03:00 committed by GitHub
parent 702b064cac
commit 19d7da3d24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 466 additions and 390 deletions

View File

@ -38,7 +38,7 @@ import (
"github.com/coder/coder/v2/agent/reconnectingpty" "github.com/coder/coder/v2/agent/reconnectingpty"
"github.com/coder/coder/v2/buildinfo" "github.com/coder/coder/v2/buildinfo"
"github.com/coder/coder/v2/cli/gitauth" "github.com/coder/coder/v2/cli/gitauth"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/codersdk/agentsdk"
"github.com/coder/coder/v2/tailnet" "github.com/coder/coder/v2/tailnet"
@ -523,7 +523,7 @@ func (a *agent) reportLifecycleLoop(ctx context.Context) {
func (a *agent) setLifecycle(ctx context.Context, state codersdk.WorkspaceAgentLifecycle) { func (a *agent) setLifecycle(ctx context.Context, state codersdk.WorkspaceAgentLifecycle) {
report := agentsdk.PostLifecycleRequest{ report := agentsdk.PostLifecycleRequest{
State: state, State: state,
ChangedAt: database.Now(), ChangedAt: dbtime.Now(),
} }
a.lifecycleMu.Lock() a.lifecycleMu.Lock()

View File

@ -13,7 +13,7 @@ import (
"github.com/coder/coder/v2/cli/clibase" "github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/cli/cliui" "github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/pty/ptytest"
) )
@ -29,13 +29,13 @@ func TestProvisionerJob(t *testing.T) {
<-test.Next <-test.Next
test.JobMutex.Lock() test.JobMutex.Lock()
test.Job.Status = codersdk.ProvisionerJobRunning test.Job.Status = codersdk.ProvisionerJobRunning
now := database.Now() now := dbtime.Now()
test.Job.StartedAt = &now test.Job.StartedAt = &now
test.JobMutex.Unlock() test.JobMutex.Unlock()
<-test.Next <-test.Next
test.JobMutex.Lock() test.JobMutex.Lock()
test.Job.Status = codersdk.ProvisionerJobSucceeded test.Job.Status = codersdk.ProvisionerJobSucceeded
now = database.Now() now = dbtime.Now()
test.Job.CompletedAt = &now test.Job.CompletedAt = &now
close(test.Logs) close(test.Logs)
test.JobMutex.Unlock() test.JobMutex.Unlock()
@ -56,17 +56,17 @@ func TestProvisionerJob(t *testing.T) {
<-test.Next <-test.Next
test.JobMutex.Lock() test.JobMutex.Lock()
test.Job.Status = codersdk.ProvisionerJobRunning test.Job.Status = codersdk.ProvisionerJobRunning
now := database.Now() now := dbtime.Now()
test.Job.StartedAt = &now test.Job.StartedAt = &now
test.Logs <- codersdk.ProvisionerJobLog{ test.Logs <- codersdk.ProvisionerJobLog{
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Stage: "Something", Stage: "Something",
} }
test.JobMutex.Unlock() test.JobMutex.Unlock()
<-test.Next <-test.Next
test.JobMutex.Lock() test.JobMutex.Lock()
test.Job.Status = codersdk.ProvisionerJobSucceeded test.Job.Status = codersdk.ProvisionerJobSucceeded
now = database.Now() now = dbtime.Now()
test.Job.CompletedAt = &now test.Job.CompletedAt = &now
close(test.Logs) close(test.Logs)
test.JobMutex.Unlock() test.JobMutex.Unlock()
@ -99,7 +99,7 @@ func TestProvisionerJob(t *testing.T) {
<-test.Next <-test.Next
test.JobMutex.Lock() test.JobMutex.Lock()
test.Job.Status = codersdk.ProvisionerJobCanceled test.Job.Status = codersdk.ProvisionerJobCanceled
now := database.Now() now := dbtime.Now()
test.Job.CompletedAt = &now test.Job.CompletedAt = &now
close(test.Logs) close(test.Logs)
test.JobMutex.Unlock() test.JobMutex.Unlock()
@ -123,7 +123,7 @@ type provisionerJobTest struct {
func newProvisionerJob(t *testing.T) provisionerJobTest { func newProvisionerJob(t *testing.T) provisionerJobTest {
job := &codersdk.ProvisionerJob{ job := &codersdk.ProvisionerJob{
Status: codersdk.ProvisionerJobPending, Status: codersdk.ProvisionerJobPending,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
} }
jobLock := sync.Mutex{} jobLock := sync.Mutex{}
logs := make(chan codersdk.ProvisionerJobLog, 1) logs := make(chan codersdk.ProvisionerJobLog, 1)

View File

@ -9,8 +9,7 @@ import (
"github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/v6/table"
"golang.org/x/mod/semver" "golang.org/x/mod/semver"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
@ -122,15 +121,15 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
func renderAgentStatus(agent codersdk.WorkspaceAgent) string { func renderAgentStatus(agent codersdk.WorkspaceAgent) string {
switch agent.Status { switch agent.Status {
case codersdk.WorkspaceAgentConnecting: case codersdk.WorkspaceAgentConnecting:
since := database.Now().Sub(agent.CreatedAt) since := dbtime.Now().Sub(agent.CreatedAt)
return DefaultStyles.Warn.Render("⦾ connecting") + " " + return DefaultStyles.Warn.Render("⦾ connecting") + " " +
DefaultStyles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]") DefaultStyles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
case codersdk.WorkspaceAgentDisconnected: case codersdk.WorkspaceAgentDisconnected:
since := database.Now().Sub(*agent.DisconnectedAt) since := dbtime.Now().Sub(*agent.DisconnectedAt)
return DefaultStyles.Error.Render("⦾ disconnected") + " " + return DefaultStyles.Error.Render("⦾ disconnected") + " " +
DefaultStyles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]") DefaultStyles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
case codersdk.WorkspaceAgentTimeout: case codersdk.WorkspaceAgentTimeout:
since := database.Now().Sub(agent.CreatedAt) since := dbtime.Now().Sub(agent.CreatedAt)
return fmt.Sprintf( return fmt.Sprintf(
"%s %s", "%s %s",
DefaultStyles.Warn.Render("⦾ timeout"), DefaultStyles.Warn.Render("⦾ timeout"),

View File

@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/coder/coder/v2/cli/cliui" "github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/pty/ptytest"
) )
@ -44,7 +44,7 @@ func TestWorkspaceResources(t *testing.T) {
t.Run("MultipleStates", func(t *testing.T) { t.Run("MultipleStates", func(t *testing.T) {
t.Parallel() t.Parallel()
ptty := ptytest.New(t) ptty := ptytest.New(t)
disconnected := database.Now().Add(-4 * time.Second) disconnected := dbtime.Now().Add(-4 * time.Second)
done := make(chan struct{}) done := make(chan struct{})
go func() { go func() {
err := cliui.WorkspaceResources(ptty.Output(), []codersdk.WorkspaceResource{{ err := cliui.WorkspaceResources(ptty.Output(), []codersdk.WorkspaceResource{{
@ -60,7 +60,7 @@ func TestWorkspaceResources(t *testing.T) {
Type: "google_compute_instance", Type: "google_compute_instance",
Name: "dev", Name: "dev",
Agents: []codersdk.WorkspaceAgent{{ Agents: []codersdk.WorkspaceAgent{{
CreatedAt: database.Now().Add(-10 * time.Second), CreatedAt: dbtime.Now().Add(-10 * time.Second),
Status: codersdk.WorkspaceAgentConnecting, Status: codersdk.WorkspaceAgentConnecting,
LifecycleState: codersdk.WorkspaceAgentLifecycleCreated, LifecycleState: codersdk.WorkspaceAgentLifecycleCreated,
Name: "dev", Name: "dev",

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/cli/clibase" "github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/cli/cliui" "github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/gitsshkey" "github.com/coder/coder/v2/coderd/gitsshkey"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -180,8 +181,8 @@ func (r *RootCmd) newCreateAdminUserCommand() *clibase.Cmd {
Email: newUserEmail, Email: newUserEmail,
Username: newUserUsername, Username: newUserUsername,
HashedPassword: []byte(hashedPassword), HashedPassword: []byte(hashedPassword),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
RBACRoles: []string{rbac.RoleOwner()}, RBACRoles: []string{rbac.RoleOwner()},
LoginType: database.LoginTypePassword, LoginType: database.LoginTypePassword,
}) })
@ -196,8 +197,8 @@ func (r *RootCmd) newCreateAdminUserCommand() *clibase.Cmd {
} }
_, err = tx.InsertGitSSHKey(ctx, database.InsertGitSSHKeyParams{ _, err = tx.InsertGitSSHKey(ctx, database.InsertGitSSHKeyParams{
UserID: newUser.ID, UserID: newUser.ID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
PrivateKey: privateKey, PrivateKey: privateKey,
PublicKey: publicKey, PublicKey: publicKey,
}) })
@ -210,8 +211,8 @@ func (r *RootCmd) newCreateAdminUserCommand() *clibase.Cmd {
_, err := tx.InsertOrganizationMember(ctx, database.InsertOrganizationMemberParams{ _, err := tx.InsertOrganizationMember(ctx, database.InsertOrganizationMemberParams{
OrganizationID: org.ID, OrganizationID: org.ID,
UserID: newUser.ID, UserID: newUser.ID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Roles: []string{rbac.RoleOrgAdmin(org.ID)}, Roles: []string{rbac.RoleOrgAdmin(org.ID)},
}) })
if err != nil { if err != nil {

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/postgres" "github.com/coder/coder/v2/coderd/database/postgres"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/userpassword" "github.com/coder/coder/v2/coderd/userpassword"
@ -106,15 +107,15 @@ func TestServerCreateAdminUser(t *testing.T) {
_, err = db.InsertOrganization(ctx, database.InsertOrganizationParams{ _, err = db.InsertOrganization(ctx, database.InsertOrganizationParams{
ID: org1ID, ID: org1ID,
Name: org1Name, Name: org1Name,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err) require.NoError(t, err)
_, err = db.InsertOrganization(ctx, database.InsertOrganizationParams{ _, err = db.InsertOrganization(ctx, database.InsertOrganizationParams{
ID: org2ID, ID: org2ID,
Name: org2Name, Name: org2Name,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err) require.NoError(t, err)

View File

@ -17,7 +17,7 @@ import (
"github.com/coder/coder/v2/cli/clibase" "github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/cli/cliui" "github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
@ -82,21 +82,21 @@ func main() {
Handler: func(inv *clibase.Invocation) error { Handler: func(inv *clibase.Invocation) error {
job := codersdk.ProvisionerJob{ job := codersdk.ProvisionerJob{
Status: codersdk.ProvisionerJobPending, Status: codersdk.ProvisionerJobPending,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
} }
go func() { go func() {
time.Sleep(time.Second) time.Sleep(time.Second)
if job.Status != codersdk.ProvisionerJobPending { if job.Status != codersdk.ProvisionerJobPending {
return return
} }
started := database.Now() started := dbtime.Now()
job.StartedAt = &started job.StartedAt = &started
job.Status = codersdk.ProvisionerJobRunning job.Status = codersdk.ProvisionerJobRunning
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
if job.Status != codersdk.ProvisionerJobRunning { if job.Status != codersdk.ProvisionerJobRunning {
return return
} }
completed := database.Now() completed := dbtime.Now()
job.CompletedAt = &completed job.CompletedAt = &completed
job.Status = codersdk.ProvisionerJobSucceeded job.Status = codersdk.ProvisionerJobSucceeded
}() }()
@ -154,7 +154,7 @@ func main() {
job.Status = codersdk.ProvisionerJobCanceling job.Status = codersdk.ProvisionerJobCanceling
time.Sleep(time.Second) time.Sleep(time.Second)
job.Status = codersdk.ProvisionerJobCanceled job.Status = codersdk.ProvisionerJobCanceled
completed := database.Now() completed := dbtime.Now()
job.CompletedAt = &completed job.CompletedAt = &completed
return nil return nil
}, },
@ -236,7 +236,7 @@ func main() {
time.Sleep(144 * time.Millisecond) time.Sleep(144 * time.Millisecond)
} }
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleReady agent.LifecycleState = codersdk.WorkspaceAgentLifecycleReady
readyAt := database.Now() readyAt := dbtime.Now()
agent.ReadyAt = &readyAt agent.ReadyAt = &readyAt
}() }()
} else { } else {
@ -258,7 +258,7 @@ func main() {
root.Children = append(root.Children, &clibase.Cmd{ root.Children = append(root.Children, &clibase.Cmd{
Use: "resources", Use: "resources",
Handler: func(inv *clibase.Invocation) error { Handler: func(inv *clibase.Invocation) error {
disconnected := database.Now().Add(-4 * time.Second) disconnected := dbtime.Now().Add(-4 * time.Second)
return cliui.WorkspaceResources(inv.Stdout, []codersdk.WorkspaceResource{{ return cliui.WorkspaceResources(inv.Stdout, []codersdk.WorkspaceResource{{
Transition: codersdk.WorkspaceTransitionStart, Transition: codersdk.WorkspaceTransitionStart,
Type: "google_compute_disk", Type: "google_compute_disk",
@ -272,7 +272,7 @@ func main() {
Type: "google_compute_instance", Type: "google_compute_instance",
Name: "dev", Name: "dev",
Agents: []codersdk.WorkspaceAgent{{ Agents: []codersdk.WorkspaceAgent{{
CreatedAt: database.Now().Add(-10 * time.Second), CreatedAt: dbtime.Now().Add(-10 * time.Second),
Status: codersdk.WorkspaceAgentConnecting, Status: codersdk.WorkspaceAgentConnecting,
LifecycleState: codersdk.WorkspaceAgentLifecycleCreated, LifecycleState: codersdk.WorkspaceAgentLifecycleCreated,
Name: "dev", Name: "dev",

View File

@ -11,6 +11,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
) )
// activityBumpWorkspace automatically bumps the workspace's auto-off timer // activityBumpWorkspace automatically bumps the workspace's auto-off timer
@ -69,14 +70,14 @@ func activityBumpWorkspace(ctx context.Context, log slog.Logger, db database.Sto
return nil return nil
} }
newDeadline := database.Now().Add(bumpAmount) newDeadline := dbtime.Now().Add(bumpAmount)
if !build.MaxDeadline.IsZero() && newDeadline.After(build.MaxDeadline) { if !build.MaxDeadline.IsZero() && newDeadline.After(build.MaxDeadline) {
newDeadline = build.MaxDeadline newDeadline = build.MaxDeadline
} }
if err := s.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{ if err := s.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{
ID: build.ID, ID: build.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
ProvisionerState: build.ProvisionerState, ProvisionerState: build.ProvisionerState,
Deadline: newDeadline, Deadline: newDeadline,
MaxDeadline: build.MaxDeadline, MaxDeadline: build.MaxDeadline,

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/schedule" "github.com/coder/coder/v2/coderd/schedule"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/codersdk/agentsdk"
@ -77,10 +78,10 @@ func TestWorkspaceActivityBump(t *testing.T) {
err = db.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{ err = db.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{
ID: workspace.LatestBuild.ID, ID: workspace.LatestBuild.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
ProvisionerState: dbBuild.ProvisionerState, ProvisionerState: dbBuild.ProvisionerState,
Deadline: dbBuild.Deadline, Deadline: dbBuild.Deadline,
MaxDeadline: database.Now().Add(maxTTL), MaxDeadline: dbtime.Now().Add(maxTTL),
}) })
require.NoError(t, err) require.NoError(t, err)
} }
@ -146,11 +147,11 @@ func TestWorkspaceActivityBump(t *testing.T) {
// If the workspace has a max deadline, the deadline must not exceed // If the workspace has a max deadline, the deadline must not exceed
// it. // it.
if maxTTL != 0 && database.Now().Add(ttl).After(workspace.LatestBuild.MaxDeadline.Time) { if maxTTL != 0 && dbtime.Now().Add(ttl).After(workspace.LatestBuild.MaxDeadline.Time) {
require.Equal(t, workspace.LatestBuild.Deadline.Time, workspace.LatestBuild.MaxDeadline.Time) require.Equal(t, workspace.LatestBuild.Deadline.Time, workspace.LatestBuild.MaxDeadline.Time)
return return
} }
require.WithinDuration(t, database.Now().Add(ttl), workspace.LatestBuild.Deadline.Time, 3*time.Second) require.WithinDuration(t, dbtime.Now().Add(ttl), workspace.LatestBuild.Deadline.Time, 3*time.Second)
} }
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/coderd/apikey" "github.com/coder/coder/v2/coderd/apikey"
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -84,7 +85,7 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
UserID: user.ID, UserID: user.ID,
LoginType: database.LoginTypeToken, LoginType: database.LoginTypeToken,
DeploymentValues: api.DeploymentValues, DeploymentValues: api.DeploymentValues,
ExpiresAt: database.Now().Add(lifeTime), ExpiresAt: dbtime.Now().Add(lifeTime),
Scope: scope, Scope: scope,
LifetimeSeconds: int64(lifeTime.Seconds()), LifetimeSeconds: int64(lifeTime.Seconds()),
TokenName: tokenName, TokenName: tokenName,
@ -132,7 +133,7 @@ func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) {
RemoteAddr: r.RemoteAddr, RemoteAddr: r.RemoteAddr,
// All api generated keys will last 1 week. Browser login tokens have // All api generated keys will last 1 week. Browser login tokens have
// a shorter life. // a shorter life.
ExpiresAt: database.Now().Add(lifeTime), ExpiresAt: dbtime.Now().Add(lifeTime),
LifetimeSeconds: int64(lifeTime.Seconds()), LifetimeSeconds: int64(lifeTime.Seconds()),
}) })
if err != nil { if err != nil {

View File

@ -11,6 +11,7 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/cryptorand" "github.com/coder/coder/v2/cryptorand"
) )
@ -43,9 +44,9 @@ func Generate(params CreateParams) (database.InsertAPIKeyParams, string, error)
// set. // set.
if params.ExpiresAt.IsZero() { if params.ExpiresAt.IsZero() {
if params.LifetimeSeconds != 0 { if params.LifetimeSeconds != 0 {
params.ExpiresAt = database.Now().Add(time.Duration(params.LifetimeSeconds) * time.Second) params.ExpiresAt = dbtime.Now().Add(time.Duration(params.LifetimeSeconds) * time.Second)
} else { } else {
params.ExpiresAt = database.Now().Add(params.DeploymentValues.SessionDuration.Value()) params.ExpiresAt = dbtime.Now().Add(params.DeploymentValues.SessionDuration.Value())
params.LifetimeSeconds = int64(params.DeploymentValues.SessionDuration.Value().Seconds()) params.LifetimeSeconds = int64(params.DeploymentValues.SessionDuration.Value().Seconds())
} }
} }
@ -85,8 +86,8 @@ func Generate(params CreateParams) (database.InsertAPIKeyParams, string, error)
}, },
// Make sure in UTC time for common time zone // Make sure in UTC time for common time zone
ExpiresAt: params.ExpiresAt.UTC(), ExpiresAt: params.ExpiresAt.UTC(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
HashedSecret: hashed[:], HashedSecret: hashed[:],
LoginType: params.LoginType, LoginType: params.LoginType,
Scope: scope, Scope: scope,

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/cli/clibase" "github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/coderd/apikey" "github.com/coder/coder/v2/coderd/apikey"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
@ -121,8 +122,8 @@ func TestGenerate(t *testing.T) {
assert.ElementsMatch(t, hashed, key.HashedSecret[:]) assert.ElementsMatch(t, hashed, key.HashedSecret[:])
assert.Equal(t, tc.params.UserID, key.UserID) assert.Equal(t, tc.params.UserID, key.UserID)
assert.WithinDuration(t, database.Now(), key.CreatedAt, time.Second*5) assert.WithinDuration(t, dbtime.Now(), key.CreatedAt, time.Second*5)
assert.WithinDuration(t, database.Now(), key.UpdatedAt, time.Second*5) assert.WithinDuration(t, dbtime.Now(), key.UpdatedAt, time.Second*5)
if tc.params.LifetimeSeconds > 0 { if tc.params.LifetimeSeconds > 0 {
assert.Equal(t, tc.params.LifetimeSeconds, key.LifetimeSeconds) assert.Equal(t, tc.params.LifetimeSeconds, key.LifetimeSeconds)
@ -136,9 +137,9 @@ func TestGenerate(t *testing.T) {
if !tc.params.ExpiresAt.IsZero() { if !tc.params.ExpiresAt.IsZero() {
assert.Equal(t, tc.params.ExpiresAt.UTC(), key.ExpiresAt) assert.Equal(t, tc.params.ExpiresAt.UTC(), key.ExpiresAt)
} else if tc.params.LifetimeSeconds > 0 { } else if tc.params.LifetimeSeconds > 0 {
assert.WithinDuration(t, database.Now().Add(time.Duration(tc.params.LifetimeSeconds)), key.ExpiresAt, time.Second*5) assert.WithinDuration(t, dbtime.Now().Add(time.Duration(tc.params.LifetimeSeconds)), key.ExpiresAt, time.Second*5)
} else { } else {
assert.WithinDuration(t, database.Now().Add(tc.params.DeploymentValues.SessionDuration.Value()), key.ExpiresAt, time.Second*5) assert.WithinDuration(t, dbtime.Now().Add(tc.params.DeploymentValues.SessionDuration.Value()), key.ExpiresAt, time.Second*5)
} }
if tc.params.RemoteAddr != "" { if tc.params.RemoteAddr != "" {

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
) )
@ -181,7 +182,7 @@ func TestSessionExpiry(t *testing.T) {
err = db.UpdateAPIKeyByID(ctx, database.UpdateAPIKeyByIDParams{ err = db.UpdateAPIKeyByID(ctx, database.UpdateAPIKeyByIDParams{
ID: apiKey.ID, ID: apiKey.ID,
LastUsed: apiKey.LastUsed, LastUsed: apiKey.LastUsed,
ExpiresAt: database.Now().Add(-time.Hour), ExpiresAt: dbtime.Now().Add(-time.Hour),
IPAddress: apiKey.IPAddress, IPAddress: apiKey.IPAddress,
}) })
require.NoError(t, err) require.NoError(t, err)

View File

@ -14,6 +14,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/tracing" "github.com/coder/coder/v2/coderd/tracing"
) )
@ -219,7 +220,7 @@ func InitRequest[T Auditable](w http.ResponseWriter, p *RequestParams) (*Request
ip := parseIP(p.Request.RemoteAddr) ip := parseIP(p.Request.RemoteAddr)
auditLog := database.AuditLog{ auditLog := database.AuditLog{
ID: uuid.New(), ID: uuid.New(),
Time: database.Now(), Time: dbtime.Now(),
UserID: userID, UserID: userID,
Ip: ip, Ip: ip,
UserAgent: sql.NullString{String: p.Request.UserAgent(), Valid: true}, UserAgent: sql.NullString{String: p.Request.UserAgent(), Valid: true},
@ -264,7 +265,7 @@ func BuildAudit[T Auditable](ctx context.Context, p *BuildAuditParams[T]) {
auditLog := database.AuditLog{ auditLog := database.AuditLog{
ID: uuid.New(), ID: uuid.New(),
Time: database.Now(), Time: dbtime.Now(),
UserID: p.UserID, UserID: p.UserID,
Ip: ip, Ip: ip,
UserAgent: sql.NullString{}, UserAgent: sql.NullString{},

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/schedule" "github.com/coder/coder/v2/coderd/schedule"
"github.com/coder/coder/v2/coderd/wsbuilder" "github.com/coder/coder/v2/coderd/wsbuilder"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -181,7 +182,7 @@ func (e *Executor) runOnce(t time.Time) Stats {
ws, err = tx.UpdateWorkspaceDormantDeletingAt(e.ctx, database.UpdateWorkspaceDormantDeletingAtParams{ ws, err = tx.UpdateWorkspaceDormantDeletingAt(e.ctx, database.UpdateWorkspaceDormantDeletingAtParams{
ID: ws.ID, ID: ws.ID,
DormantAt: sql.NullTime{ DormantAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
}) })

View File

@ -15,6 +15,7 @@ import (
"cdr.dev/slog/sloggers/sloghuman" "cdr.dev/slog/sloggers/sloghuman"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/codersdk/agentsdk"
) )
@ -137,7 +138,7 @@ func (b *Batcher) Add(
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
now = database.Time(now) now = dbtime.Time(now)
b.buf.ID = append(b.buf.ID, uuid.New()) b.buf.ID = append(b.buf.ID, uuid.New())
b.buf.CreatedAt = append(b.buf.CreatedAt, now) b.buf.CreatedAt = append(b.buf.CreatedAt, now)

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/codersdk/agentsdk"
"github.com/coder/coder/v2/cryptorand" "github.com/coder/coder/v2/cryptorand"
@ -46,7 +47,7 @@ func TestBatchStats(t *testing.T) {
// Given: no data points are added for workspace // Given: no data points are added for workspace
// When: it becomes time to report stats // When: it becomes time to report stats
t1 := database.Now() t1 := dbtime.Now()
// Signal a tick and wait for a flush to complete. // Signal a tick and wait for a flush to complete.
tick <- t1 tick <- t1
f := <-flushed f := <-flushed

View File

@ -46,6 +46,7 @@ import (
"github.com/coder/coder/v2/coderd/batchstats" "github.com/coder/coder/v2/coderd/batchstats"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub" "github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/coder/coder/v2/coderd/gitauth" "github.com/coder/coder/v2/coderd/gitauth"
"github.com/coder/coder/v2/coderd/gitsshkey" "github.com/coder/coder/v2/coderd/gitsshkey"
@ -1081,7 +1082,7 @@ func (api *API) CreateInMemoryProvisionerDaemon(ctx context.Context, debounce ti
// nolint:gocritic // Inserting a provisioner daemon is a system function. // nolint:gocritic // Inserting a provisioner daemon is a system function.
daemon, err := api.Database.InsertProvisionerDaemon(dbauthz.AsSystemRestricted(ctx), database.InsertProvisionerDaemonParams{ daemon, err := api.Database.InsertProvisionerDaemon(dbauthz.AsSystemRestricted(ctx), database.InsertProvisionerDaemonParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Name: name, Name: name,
Provisioners: []database.ProvisionerType{database.ProvisionerTypeEcho, database.ProvisionerTypeTerraform}, Provisioners: []database.ProvisionerType{database.ProvisionerTypeEcho, database.ProvisionerTypeTerraform},
Tags: database.StringMap{ Tags: database.StringMap{

View File

@ -11,6 +11,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/provisionersdk/proto" "github.com/coder/coder/v2/provisionersdk/proto"
) )
@ -27,7 +28,7 @@ func TestProvisionerJobStatus(t *testing.T) {
name: "canceling", name: "canceling",
job: database.ProvisionerJob{ job: database.ProvisionerJob{
CanceledAt: sql.NullTime{ CanceledAt: sql.NullTime{
Time: database.Now().Add(-time.Minute), Time: dbtime.Now().Add(-time.Minute),
Valid: true, Valid: true,
}, },
}, },
@ -37,11 +38,11 @@ func TestProvisionerJobStatus(t *testing.T) {
name: "canceled", name: "canceled",
job: database.ProvisionerJob{ job: database.ProvisionerJob{
CanceledAt: sql.NullTime{ CanceledAt: sql.NullTime{
Time: database.Now().Add(-time.Minute), Time: dbtime.Now().Add(-time.Minute),
Valid: true, Valid: true,
}, },
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now().Add(-30 * time.Second), Time: dbtime.Now().Add(-30 * time.Second),
Valid: true, Valid: true,
}, },
}, },
@ -51,11 +52,11 @@ func TestProvisionerJobStatus(t *testing.T) {
name: "canceled_failed", name: "canceled_failed",
job: database.ProvisionerJob{ job: database.ProvisionerJob{
CanceledAt: sql.NullTime{ CanceledAt: sql.NullTime{
Time: database.Now().Add(-time.Minute), Time: dbtime.Now().Add(-time.Minute),
Valid: true, Valid: true,
}, },
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now().Add(-30 * time.Second), Time: dbtime.Now().Add(-30 * time.Second),
Valid: true, Valid: true,
}, },
Error: sql.NullString{String: "badness", Valid: true}, Error: sql.NullString{String: "badness", Valid: true},
@ -71,11 +72,11 @@ func TestProvisionerJobStatus(t *testing.T) {
name: "succeeded", name: "succeeded",
job: database.ProvisionerJob{ job: database.ProvisionerJob{
StartedAt: sql.NullTime{ StartedAt: sql.NullTime{
Time: database.Now().Add(-time.Minute), Time: dbtime.Now().Add(-time.Minute),
Valid: true, Valid: true,
}, },
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now().Add(-30 * time.Second), Time: dbtime.Now().Add(-30 * time.Second),
Valid: true, Valid: true,
}, },
}, },
@ -85,11 +86,11 @@ func TestProvisionerJobStatus(t *testing.T) {
name: "completed_failed", name: "completed_failed",
job: database.ProvisionerJob{ job: database.ProvisionerJob{
StartedAt: sql.NullTime{ StartedAt: sql.NullTime{
Time: database.Now().Add(-time.Minute), Time: dbtime.Now().Add(-time.Minute),
Valid: true, Valid: true,
}, },
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now().Add(-30 * time.Second), Time: dbtime.Now().Add(-30 * time.Second),
Valid: true, Valid: true,
}, },
Error: sql.NullString{String: "badness", Valid: true}, Error: sql.NullString{String: "badness", Valid: true},
@ -100,10 +101,10 @@ func TestProvisionerJobStatus(t *testing.T) {
name: "updated", name: "updated",
job: database.ProvisionerJob{ job: database.ProvisionerJob{
StartedAt: sql.NullTime{ StartedAt: sql.NullTime{
Time: database.Now().Add(-time.Minute), Time: dbtime.Now().Add(-time.Minute),
Valid: true, Valid: true,
}, },
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}, },
status: codersdk.ProvisionerJobRunning, status: codersdk.ProvisionerJobRunning,
}, },

View File

@ -12,6 +12,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/migrations" "github.com/coder/coder/v2/coderd/database/migrations"
"github.com/coder/coder/v2/coderd/database/postgres" "github.com/coder/coder/v2/coderd/database/postgres"
) )
@ -68,8 +69,8 @@ func TestNestedInTx(t *testing.T) {
Email: "coder@coder.com", Email: "coder@coder.com",
Username: "coder", Username: "coder",
HashedPassword: []byte{}, HashedPassword: []byte{},
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
RBACRoles: []string{}, RBACRoles: []string{},
LoginType: database.LoginTypeGithub, LoginType: database.LoginTypeGithub,
}) })

View File

@ -16,6 +16,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/util/slice" "github.com/coder/coder/v2/coderd/util/slice"
) )
@ -580,7 +581,7 @@ func (q *querier) SoftDeleteTemplateByID(ctx context.Context, id uuid.UUID) erro
return q.db.UpdateTemplateDeletedByID(ctx, database.UpdateTemplateDeletedByIDParams{ return q.db.UpdateTemplateDeletedByID(ctx, database.UpdateTemplateDeletedByIDParams{
ID: id, ID: id,
Deleted: true, Deleted: true,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
} }
return deleteQ(q.log, q.auth, q.db.GetTemplateByID, deleteF)(ctx, id) return deleteQ(q.log, q.auth, q.db.GetTemplateByID, deleteF)(ctx, id)

View File

@ -18,6 +18,7 @@ import (
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/util/slice" "github.com/coder/coder/v2/coderd/util/slice"
) )
@ -863,8 +864,8 @@ func (s *MethodTestSuite) TestUser() {
check.Args(u.ID).Asserts(u, rbac.ActionRead).Returns(u) check.Args(u.ID).Asserts(u, rbac.ActionRead).Returns(u)
})) }))
s.Run("GetUsersByIDs", s.Subtest(func(db database.Store, check *expects) { s.Run("GetUsersByIDs", s.Subtest(func(db database.Store, check *expects) {
a := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now().Add(-time.Hour)}) a := dbgen.User(s.T(), db, database.User{CreatedAt: dbtime.Now().Add(-time.Hour)})
b := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now()}) b := dbgen.User(s.T(), db, database.User{CreatedAt: dbtime.Now()})
check.Args([]uuid.UUID{a.ID, b.ID}). check.Args([]uuid.UUID{a.ID, b.ID}).
Asserts(a, rbac.ActionRead, b, rbac.ActionRead). Asserts(a, rbac.ActionRead, b, rbac.ActionRead).
Returns(slice.New(a, b)) Returns(slice.New(a, b))

View File

@ -21,6 +21,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/rbac/regosql" "github.com/coder/coder/v2/coderd/rbac/regosql"
@ -300,7 +301,7 @@ func mapAgentStatus(dbAgent database.WorkspaceAgent, agentInactiveDisconnectTime
switch { switch {
case !dbAgent.FirstConnectedAt.Valid: case !dbAgent.FirstConnectedAt.Valid:
switch { switch {
case connectionTimeout > 0 && database.Now().Sub(dbAgent.CreatedAt) > connectionTimeout: case connectionTimeout > 0 && dbtime.Now().Sub(dbAgent.CreatedAt) > connectionTimeout:
// If the agent took too long to connect the first time, // If the agent took too long to connect the first time,
// mark it as timed out. // mark it as timed out.
status = "timeout" status = "timeout"
@ -313,7 +314,7 @@ func mapAgentStatus(dbAgent database.WorkspaceAgent, agentInactiveDisconnectTime
// If we've disconnected after our last connection, we know the // If we've disconnected after our last connection, we know the
// agent is no longer connected. // agent is no longer connected.
status = "disconnected" status = "disconnected"
case database.Now().Sub(dbAgent.LastConnectedAt.Time) > time.Duration(agentInactiveDisconnectTimeoutSeconds)*time.Second: case dbtime.Now().Sub(dbAgent.LastConnectedAt.Time) > time.Duration(agentInactiveDisconnectTimeoutSeconds)*time.Second:
// The connection died without updating the last connected. // The connection died without updating the last connected.
status = "disconnected" status = "disconnected"
case dbAgent.LastConnectedAt.Valid: case dbAgent.LastConnectedAt.Valid:
@ -4784,7 +4785,7 @@ func (q *FakeQuerier) RegisterWorkspaceProxy(_ context.Context, arg database.Reg
p.WildcardHostname = arg.WildcardHostname p.WildcardHostname = arg.WildcardHostname
p.DerpEnabled = arg.DerpEnabled p.DerpEnabled = arg.DerpEnabled
p.DerpOnly = arg.DerpOnly p.DerpOnly = arg.DerpOnly
p.UpdatedAt = database.Now() p.UpdatedAt = dbtime.Now()
q.workspaceProxies[i] = p q.workspaceProxies[i] = p
return p, nil return p, nil
} }
@ -5099,7 +5100,7 @@ func (q *FakeQuerier) UpdateTemplateMetaByID(_ context.Context, arg database.Upd
if tpl.ID != arg.ID { if tpl.ID != arg.ID {
continue continue
} }
tpl.UpdatedAt = database.Now() tpl.UpdatedAt = dbtime.Now()
tpl.Name = arg.Name tpl.Name = arg.Name
tpl.DisplayName = arg.DisplayName tpl.DisplayName = arg.DisplayName
tpl.Description = arg.Description tpl.Description = arg.Description
@ -5125,7 +5126,7 @@ func (q *FakeQuerier) UpdateTemplateScheduleByID(_ context.Context, arg database
} }
tpl.AllowUserAutostart = arg.AllowUserAutostart tpl.AllowUserAutostart = arg.AllowUserAutostart
tpl.AllowUserAutostop = arg.AllowUserAutostop tpl.AllowUserAutostop = arg.AllowUserAutostop
tpl.UpdatedAt = database.Now() tpl.UpdatedAt = dbtime.Now()
tpl.DefaultTTL = arg.DefaultTTL tpl.DefaultTTL = arg.DefaultTTL
tpl.MaxTTL = arg.MaxTTL tpl.MaxTTL = arg.MaxTTL
tpl.AutostopRequirementDaysOfWeek = arg.AutostopRequirementDaysOfWeek tpl.AutostopRequirementDaysOfWeek = arg.AutostopRequirementDaysOfWeek
@ -5712,7 +5713,7 @@ func (q *FakeQuerier) UpdateWorkspaceDormantDeletingAt(_ context.Context, arg da
} }
workspace.DormantAt = arg.DormantAt workspace.DormantAt = arg.DormantAt
if workspace.DormantAt.Time.IsZero() { if workspace.DormantAt.Time.IsZero() {
workspace.LastUsedAt = database.Now() workspace.LastUsedAt = dbtime.Now()
workspace.DeletingAt = sql.NullTime{} workspace.DeletingAt = sql.NullTime{}
} }
if !workspace.DormantAt.Time.IsZero() { if !workspace.DormantAt.Time.IsZero() {
@ -5791,7 +5792,7 @@ func (q *FakeQuerier) UpdateWorkspaceProxyDeleted(_ context.Context, arg databas
for i, p := range q.workspaceProxies { for i, p := range q.workspaceProxies {
if p.ID == arg.ID { if p.ID == arg.ID {
p.Deleted = arg.Deleted p.Deleted = arg.Deleted
p.UpdatedAt = database.Now() p.UpdatedAt = dbtime.Now()
q.workspaceProxies[i] = p q.workspaceProxies[i] = p
return nil return nil
} }

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
) )
// test that transactions don't deadlock, and that we don't see intermediate state. // test that transactions don't deadlock, and that we don't see intermediate state.
@ -67,7 +68,7 @@ func TestUserOrder(t *testing.T) {
t.Parallel() t.Parallel()
db := dbfake.New() db := dbfake.New()
now := database.Now() now := dbtime.Now()
usernames := []string{"b-user", "d-user", "a-user", "c-user", "e-user"} usernames := []string{"b-user", "d-user", "a-user", "c-user", "e-user"}
for _, username := range usernames { for _, username := range usernames {

View File

@ -18,6 +18,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/cryptorand" "github.com/coder/coder/v2/cryptorand"
) )
@ -36,7 +37,7 @@ var genCtx = dbauthz.As(context.Background(), rbac.Subject{
func AuditLog(t testing.TB, db database.Store, seed database.AuditLog) database.AuditLog { func AuditLog(t testing.TB, db database.Store, seed database.AuditLog) database.AuditLog {
log, err := db.InsertAuditLog(genCtx, database.InsertAuditLogParams{ log, err := db.InsertAuditLog(genCtx, database.InsertAuditLogParams{
ID: takeFirst(seed.ID, uuid.New()), ID: takeFirst(seed.ID, uuid.New()),
Time: takeFirst(seed.Time, database.Now()), Time: takeFirst(seed.Time, dbtime.Now()),
UserID: takeFirst(seed.UserID, uuid.New()), UserID: takeFirst(seed.UserID, uuid.New()),
OrganizationID: takeFirst(seed.OrganizationID, uuid.New()), OrganizationID: takeFirst(seed.OrganizationID, uuid.New()),
Ip: pqtype.Inet{ Ip: pqtype.Inet{
@ -65,8 +66,8 @@ func Template(t testing.TB, db database.Store, seed database.Template) database.
id := takeFirst(seed.ID, uuid.New()) id := takeFirst(seed.ID, uuid.New())
err := db.InsertTemplate(genCtx, database.InsertTemplateParams{ err := db.InsertTemplate(genCtx, database.InsertTemplateParams{
ID: id, ID: id,
CreatedAt: takeFirst(seed.CreatedAt, database.Now()), CreatedAt: takeFirst(seed.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(seed.UpdatedAt, database.Now()), UpdatedAt: takeFirst(seed.UpdatedAt, dbtime.Now()),
OrganizationID: takeFirst(seed.OrganizationID, uuid.New()), OrganizationID: takeFirst(seed.OrganizationID, uuid.New()),
Name: takeFirst(seed.Name, namesgenerator.GetRandomName(1)), Name: takeFirst(seed.Name, namesgenerator.GetRandomName(1)),
Provisioner: takeFirst(seed.Provisioner, database.ProvisionerTypeEcho), Provisioner: takeFirst(seed.Provisioner, database.ProvisionerTypeEcho),
@ -109,10 +110,10 @@ func APIKey(t testing.TB, db database.Store, seed database.APIKey) (key database
HashedSecret: takeFirstSlice(seed.HashedSecret, hashed[:]), HashedSecret: takeFirstSlice(seed.HashedSecret, hashed[:]),
IPAddress: ip, IPAddress: ip,
UserID: takeFirst(seed.UserID, uuid.New()), UserID: takeFirst(seed.UserID, uuid.New()),
LastUsed: takeFirst(seed.LastUsed, database.Now()), LastUsed: takeFirst(seed.LastUsed, dbtime.Now()),
ExpiresAt: takeFirst(seed.ExpiresAt, database.Now().Add(time.Hour)), ExpiresAt: takeFirst(seed.ExpiresAt, dbtime.Now().Add(time.Hour)),
CreatedAt: takeFirst(seed.CreatedAt, database.Now()), CreatedAt: takeFirst(seed.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(seed.UpdatedAt, database.Now()), UpdatedAt: takeFirst(seed.UpdatedAt, dbtime.Now()),
LoginType: takeFirst(seed.LoginType, database.LoginTypePassword), LoginType: takeFirst(seed.LoginType, database.LoginTypePassword),
Scope: takeFirst(seed.Scope, database.APIKeyScopeAll), Scope: takeFirst(seed.Scope, database.APIKeyScopeAll),
TokenName: takeFirst(seed.TokenName), TokenName: takeFirst(seed.TokenName),
@ -124,8 +125,8 @@ func APIKey(t testing.TB, db database.Store, seed database.APIKey) (key database
func WorkspaceAgent(t testing.TB, db database.Store, orig database.WorkspaceAgent) database.WorkspaceAgent { func WorkspaceAgent(t testing.TB, db database.Store, orig database.WorkspaceAgent) database.WorkspaceAgent {
workspace, err := db.InsertWorkspaceAgent(genCtx, database.InsertWorkspaceAgentParams{ workspace, err := db.InsertWorkspaceAgent(genCtx, database.InsertWorkspaceAgentParams{
ID: takeFirst(orig.ID, uuid.New()), ID: takeFirst(orig.ID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)), Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
ResourceID: takeFirst(orig.ResourceID, uuid.New()), ResourceID: takeFirst(orig.ResourceID, uuid.New()),
AuthToken: takeFirst(orig.AuthToken, uuid.New()), AuthToken: takeFirst(orig.AuthToken, uuid.New()),
@ -166,11 +167,11 @@ func Workspace(t testing.TB, db database.Store, orig database.Workspace) databas
workspace, err := db.InsertWorkspace(genCtx, database.InsertWorkspaceParams{ workspace, err := db.InsertWorkspace(genCtx, database.InsertWorkspaceParams{
ID: takeFirst(orig.ID, uuid.New()), ID: takeFirst(orig.ID, uuid.New()),
OwnerID: takeFirst(orig.OwnerID, uuid.New()), OwnerID: takeFirst(orig.OwnerID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()), OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
TemplateID: takeFirst(orig.TemplateID, uuid.New()), TemplateID: takeFirst(orig.TemplateID, uuid.New()),
LastUsedAt: takeFirst(orig.LastUsedAt, database.Now()), LastUsedAt: takeFirst(orig.LastUsedAt, dbtime.Now()),
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)), Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
AutostartSchedule: orig.AutostartSchedule, AutostartSchedule: orig.AutostartSchedule,
Ttl: orig.Ttl, Ttl: orig.Ttl,
@ -185,8 +186,8 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
err := db.InTx(func(db database.Store) error { err := db.InTx(func(db database.Store) error {
err := db.InsertWorkspaceBuild(genCtx, database.InsertWorkspaceBuildParams{ err := db.InsertWorkspaceBuild(genCtx, database.InsertWorkspaceBuildParams{
ID: buildID, ID: buildID,
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
WorkspaceID: takeFirst(orig.WorkspaceID, uuid.New()), WorkspaceID: takeFirst(orig.WorkspaceID, uuid.New()),
TemplateVersionID: takeFirst(orig.TemplateVersionID, uuid.New()), TemplateVersionID: takeFirst(orig.TemplateVersionID, uuid.New()),
BuildNumber: takeFirst(orig.BuildNumber, 1), BuildNumber: takeFirst(orig.BuildNumber, 1),
@ -194,7 +195,7 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
InitiatorID: takeFirst(orig.InitiatorID, uuid.New()), InitiatorID: takeFirst(orig.InitiatorID, uuid.New()),
JobID: takeFirst(orig.JobID, uuid.New()), JobID: takeFirst(orig.JobID, uuid.New()),
ProvisionerState: takeFirstSlice(orig.ProvisionerState, []byte{}), ProvisionerState: takeFirstSlice(orig.ProvisionerState, []byte{}),
Deadline: takeFirst(orig.Deadline, database.Now().Add(time.Hour)), Deadline: takeFirst(orig.Deadline, dbtime.Now().Add(time.Hour)),
Reason: takeFirst(orig.Reason, database.BuildReasonInitiator), Reason: takeFirst(orig.Reason, database.BuildReasonInitiator),
}) })
if err != nil { if err != nil {
@ -217,8 +218,8 @@ func User(t testing.TB, db database.Store, orig database.User) database.User {
Email: takeFirst(orig.Email, namesgenerator.GetRandomName(1)), Email: takeFirst(orig.Email, namesgenerator.GetRandomName(1)),
Username: takeFirst(orig.Username, namesgenerator.GetRandomName(1)), Username: takeFirst(orig.Username, namesgenerator.GetRandomName(1)),
HashedPassword: takeFirstSlice(orig.HashedPassword, []byte(must(cryptorand.String(32)))), HashedPassword: takeFirstSlice(orig.HashedPassword, []byte(must(cryptorand.String(32)))),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
RBACRoles: takeFirstSlice(orig.RBACRoles, []string{}), RBACRoles: takeFirstSlice(orig.RBACRoles, []string{}),
LoginType: takeFirst(orig.LoginType, database.LoginTypePassword), LoginType: takeFirst(orig.LoginType, database.LoginTypePassword),
}) })
@ -227,7 +228,7 @@ func User(t testing.TB, db database.Store, orig database.User) database.User {
user, err = db.UpdateUserStatus(genCtx, database.UpdateUserStatusParams{ user, err = db.UpdateUserStatus(genCtx, database.UpdateUserStatusParams{
ID: user.ID, ID: user.ID,
Status: database.UserStatusActive, Status: database.UserStatusActive,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err, "insert user") require.NoError(t, err, "insert user")
@ -245,8 +246,8 @@ func User(t testing.TB, db database.Store, orig database.User) database.User {
func GitSSHKey(t testing.TB, db database.Store, orig database.GitSSHKey) database.GitSSHKey { func GitSSHKey(t testing.TB, db database.Store, orig database.GitSSHKey) database.GitSSHKey {
key, err := db.InsertGitSSHKey(genCtx, database.InsertGitSSHKeyParams{ key, err := db.InsertGitSSHKey(genCtx, database.InsertGitSSHKeyParams{
UserID: takeFirst(orig.UserID, uuid.New()), UserID: takeFirst(orig.UserID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
PrivateKey: takeFirst(orig.PrivateKey, ""), PrivateKey: takeFirst(orig.PrivateKey, ""),
PublicKey: takeFirst(orig.PublicKey, ""), PublicKey: takeFirst(orig.PublicKey, ""),
}) })
@ -259,8 +260,8 @@ func Organization(t testing.TB, db database.Store, orig database.Organization) d
ID: takeFirst(orig.ID, uuid.New()), ID: takeFirst(orig.ID, uuid.New()),
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)), Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
Description: takeFirst(orig.Description, namesgenerator.GetRandomName(1)), Description: takeFirst(orig.Description, namesgenerator.GetRandomName(1)),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
}) })
require.NoError(t, err, "insert organization") require.NoError(t, err, "insert organization")
return org return org
@ -270,8 +271,8 @@ func OrganizationMember(t testing.TB, db database.Store, orig database.Organizat
mem, err := db.InsertOrganizationMember(genCtx, database.InsertOrganizationMemberParams{ mem, err := db.InsertOrganizationMember(genCtx, database.InsertOrganizationMemberParams{
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()), OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
UserID: takeFirst(orig.UserID, uuid.New()), UserID: takeFirst(orig.UserID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
Roles: takeFirstSlice(orig.Roles, []string{}), Roles: takeFirstSlice(orig.Roles, []string{}),
}) })
require.NoError(t, err, "insert organization") require.NoError(t, err, "insert organization")
@ -320,8 +321,8 @@ func ProvisionerJob(t testing.TB, db database.Store, orig database.ProvisionerJo
jobID := takeFirst(orig.ID, uuid.New()) jobID := takeFirst(orig.ID, uuid.New())
job, err := db.InsertProvisionerJob(genCtx, database.InsertProvisionerJobParams{ job, err := db.InsertProvisionerJob(genCtx, database.InsertProvisionerJobParams{
ID: jobID, ID: jobID,
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()), OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
InitiatorID: takeFirst(orig.InitiatorID, uuid.New()), InitiatorID: takeFirst(orig.InitiatorID, uuid.New()),
Provisioner: takeFirst(orig.Provisioner, database.ProvisionerTypeEcho), Provisioner: takeFirst(orig.Provisioner, database.ProvisionerTypeEcho),
@ -370,7 +371,7 @@ func ProvisionerJob(t testing.TB, db database.Store, orig database.ProvisionerJo
func WorkspaceApp(t testing.TB, db database.Store, orig database.WorkspaceApp) database.WorkspaceApp { func WorkspaceApp(t testing.TB, db database.Store, orig database.WorkspaceApp) database.WorkspaceApp {
resource, err := db.InsertWorkspaceApp(genCtx, database.InsertWorkspaceAppParams{ resource, err := db.InsertWorkspaceApp(genCtx, database.InsertWorkspaceAppParams{
ID: takeFirst(orig.ID, uuid.New()), ID: takeFirst(orig.ID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
AgentID: takeFirst(orig.AgentID, uuid.New()), AgentID: takeFirst(orig.AgentID, uuid.New()),
Slug: takeFirst(orig.Slug, namesgenerator.GetRandomName(1)), Slug: takeFirst(orig.Slug, namesgenerator.GetRandomName(1)),
DisplayName: takeFirst(orig.DisplayName, namesgenerator.GetRandomName(1)), DisplayName: takeFirst(orig.DisplayName, namesgenerator.GetRandomName(1)),
@ -398,7 +399,7 @@ func WorkspaceApp(t testing.TB, db database.Store, orig database.WorkspaceApp) d
func WorkspaceResource(t testing.TB, db database.Store, orig database.WorkspaceResource) database.WorkspaceResource { func WorkspaceResource(t testing.TB, db database.Store, orig database.WorkspaceResource) database.WorkspaceResource {
resource, err := db.InsertWorkspaceResource(genCtx, database.InsertWorkspaceResourceParams{ resource, err := db.InsertWorkspaceResource(genCtx, database.InsertWorkspaceResourceParams{
ID: takeFirst(orig.ID, uuid.New()), ID: takeFirst(orig.ID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
JobID: takeFirst(orig.JobID, uuid.New()), JobID: takeFirst(orig.JobID, uuid.New()),
Transition: takeFirst(orig.Transition, database.WorkspaceTransitionStart), Transition: takeFirst(orig.Transition, database.WorkspaceTransitionStart),
Type: takeFirst(orig.Type, "fake_resource"), Type: takeFirst(orig.Type, "fake_resource"),
@ -437,8 +438,8 @@ func WorkspaceProxy(t testing.TB, db database.Store, orig database.WorkspaceProx
DisplayName: takeFirst(orig.DisplayName, namesgenerator.GetRandomName(1)), DisplayName: takeFirst(orig.DisplayName, namesgenerator.GetRandomName(1)),
Icon: takeFirst(orig.Icon, namesgenerator.GetRandomName(1)), Icon: takeFirst(orig.Icon, namesgenerator.GetRandomName(1)),
TokenHashedSecret: hashedSecret[:], TokenHashedSecret: hashedSecret[:],
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
}) })
require.NoError(t, err, "insert proxy") require.NoError(t, err, "insert proxy")
@ -458,7 +459,7 @@ func File(t testing.TB, db database.Store, orig database.File) database.File {
file, err := db.InsertFile(genCtx, database.InsertFileParams{ file, err := db.InsertFile(genCtx, database.InsertFileParams{
ID: takeFirst(orig.ID, uuid.New()), ID: takeFirst(orig.ID, uuid.New()),
Hash: takeFirst(orig.Hash, hex.EncodeToString(make([]byte, 32))), Hash: takeFirst(orig.Hash, hex.EncodeToString(make([]byte, 32))),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
CreatedBy: takeFirst(orig.CreatedBy, uuid.New()), CreatedBy: takeFirst(orig.CreatedBy, uuid.New()),
Mimetype: takeFirst(orig.Mimetype, "application/x-tar"), Mimetype: takeFirst(orig.Mimetype, "application/x-tar"),
Data: takeFirstSlice(orig.Data, []byte{}), Data: takeFirstSlice(orig.Data, []byte{}),
@ -474,7 +475,7 @@ func UserLink(t testing.TB, db database.Store, orig database.UserLink) database.
LinkedID: takeFirst(orig.LinkedID), LinkedID: takeFirst(orig.LinkedID),
OAuthAccessToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()), OAuthAccessToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()),
OAuthRefreshToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()), OAuthRefreshToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()),
OAuthExpiry: takeFirst(orig.OAuthExpiry, database.Now().Add(time.Hour*24)), OAuthExpiry: takeFirst(orig.OAuthExpiry, dbtime.Now().Add(time.Hour*24)),
}) })
require.NoError(t, err, "insert link") require.NoError(t, err, "insert link")
@ -487,9 +488,9 @@ func GitAuthLink(t testing.TB, db database.Store, orig database.GitAuthLink) dat
UserID: takeFirst(orig.UserID, uuid.New()), UserID: takeFirst(orig.UserID, uuid.New()),
OAuthAccessToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()), OAuthAccessToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()),
OAuthRefreshToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()), OAuthRefreshToken: takeFirst(orig.OAuthAccessToken, uuid.NewString()),
OAuthExpiry: takeFirst(orig.OAuthExpiry, database.Now().Add(time.Hour*24)), OAuthExpiry: takeFirst(orig.OAuthExpiry, dbtime.Now().Add(time.Hour*24)),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
}) })
require.NoError(t, err, "insert git auth link") require.NoError(t, err, "insert git auth link")
@ -504,8 +505,8 @@ func TemplateVersion(t testing.TB, db database.Store, orig database.TemplateVers
ID: versionID, ID: versionID,
TemplateID: orig.TemplateID, TemplateID: orig.TemplateID,
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()), OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UpdatedAt: takeFirst(orig.UpdatedAt, database.Now()), UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)), Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
Message: orig.Message, Message: orig.Message,
Readme: takeFirst(orig.Readme, namesgenerator.GetRandomName(1)), Readme: takeFirst(orig.Readme, namesgenerator.GetRandomName(1)),
@ -548,7 +549,7 @@ func WorkspaceAgentStat(t testing.TB, db database.Store, orig database.Workspace
} }
scheme, err := db.InsertWorkspaceAgentStat(genCtx, database.InsertWorkspaceAgentStatParams{ scheme, err := db.InsertWorkspaceAgentStat(genCtx, database.InsertWorkspaceAgentStatParams{
ID: takeFirst(orig.ID, uuid.New()), ID: takeFirst(orig.ID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, database.Now()), CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
UserID: takeFirst(orig.UserID, uuid.New()), UserID: takeFirst(orig.UserID, uuid.New()),
TemplateID: takeFirst(orig.TemplateID, uuid.New()), TemplateID: takeFirst(orig.TemplateID, uuid.New()),
WorkspaceID: takeFirst(orig.WorkspaceID, uuid.New()), WorkspaceID: takeFirst(orig.WorkspaceID, uuid.New()),

View File

@ -0,0 +1,14 @@
package dbtime
import "time"
// Now returns a standardized timezone used for database resources.
func Now() time.Time {
return Time(time.Now().UTC())
}
// Time returns a time compatible with Postgres. Postgres only stores dates with
// microsecond precision.
func Time(t time.Time) time.Time {
return t.Round(time.Microsecond)
}

View File

@ -7,6 +7,7 @@ import (
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
) )
@ -289,7 +290,7 @@ func (a WorkspaceAgent) Status(inactiveTimeout time.Duration) WorkspaceAgentConn
switch { switch {
case !a.FirstConnectedAt.Valid: case !a.FirstConnectedAt.Valid:
switch { switch {
case connectionTimeout > 0 && Now().Sub(a.CreatedAt) > connectionTimeout: case connectionTimeout > 0 && dbtime.Now().Sub(a.CreatedAt) > connectionTimeout:
// If the agent took too long to connect the first time, // If the agent took too long to connect the first time,
// mark it as timed out. // mark it as timed out.
status.Status = WorkspaceAgentStatusTimeout status.Status = WorkspaceAgentStatusTimeout
@ -304,7 +305,7 @@ func (a WorkspaceAgent) Status(inactiveTimeout time.Duration) WorkspaceAgentConn
// If we've disconnected after our last connection, we know the // If we've disconnected after our last connection, we know the
// agent is no longer connected. // agent is no longer connected.
status.Status = WorkspaceAgentStatusDisconnected status.Status = WorkspaceAgentStatusDisconnected
case Now().Sub(a.LastConnectedAt.Time) > inactiveTimeout: case dbtime.Now().Sub(a.LastConnectedAt.Time) > inactiveTimeout:
// The connection died without updating the last connected. // The connection died without updating the last connected.
status.Status = WorkspaceAgentStatusDisconnected status.Status = WorkspaceAgentStatusDisconnected
// Client code needs an accurate disconnected at if the agent has been inactive. // Client code needs an accurate disconnected at if the agent has been inactive.

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/migrations" "github.com/coder/coder/v2/coderd/database/migrations"
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
) )
@ -43,7 +44,7 @@ func TestGetDeploymentWorkspaceAgentStats(t *testing.T) {
ConnectionMedianLatencyMS: 2, ConnectionMedianLatencyMS: 2,
SessionCountVSCode: 1, SessionCountVSCode: 1,
}) })
stats, err := db.GetDeploymentWorkspaceAgentStats(ctx, database.Now().Add(-time.Hour)) stats, err := db.GetDeploymentWorkspaceAgentStats(ctx, dbtime.Now().Add(-time.Hour))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int64(2), stats.WorkspaceTxBytes) require.Equal(t, int64(2), stats.WorkspaceTxBytes)
@ -62,7 +63,7 @@ func TestGetDeploymentWorkspaceAgentStats(t *testing.T) {
db := database.New(sqlDB) db := database.New(sqlDB)
ctx := context.Background() ctx := context.Background()
agentID := uuid.New() agentID := uuid.New()
insertTime := database.Now() insertTime := dbtime.Now()
dbgen.WorkspaceAgentStat(t, db, database.WorkspaceAgentStat{ dbgen.WorkspaceAgentStat(t, db, database.WorkspaceAgentStat{
CreatedAt: insertTime.Add(-time.Second), CreatedAt: insertTime.Add(-time.Second),
AgentID: agentID, AgentID: agentID,
@ -80,7 +81,7 @@ func TestGetDeploymentWorkspaceAgentStats(t *testing.T) {
ConnectionMedianLatencyMS: 2, ConnectionMedianLatencyMS: 2,
SessionCountVSCode: 1, SessionCountVSCode: 1,
}) })
stats, err := db.GetDeploymentWorkspaceAgentStats(ctx, database.Now().Add(-time.Hour)) stats, err := db.GetDeploymentWorkspaceAgentStats(ctx, dbtime.Now().Add(-time.Hour))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int64(2), stats.WorkspaceTxBytes) require.Equal(t, int64(2), stats.WorkspaceTxBytes)
@ -113,7 +114,7 @@ func TestInsertWorkspaceAgentLogs(t *testing.T) {
}) })
logs, err := db.InsertWorkspaceAgentLogs(ctx, database.InsertWorkspaceAgentLogsParams{ logs, err := db.InsertWorkspaceAgentLogs(ctx, database.InsertWorkspaceAgentLogsParams{
AgentID: agent.ID, AgentID: agent.ID,
CreatedAt: []time.Time{database.Now()}, CreatedAt: []time.Time{dbtime.Now()},
Output: []string{"first"}, Output: []string{"first"},
Level: []database.LogLevel{database.LogLevelInfo}, Level: []database.LogLevel{database.LogLevelInfo},
Source: []database.WorkspaceAgentLogSource{database.WorkspaceAgentLogSourceExternal}, Source: []database.WorkspaceAgentLogSource{database.WorkspaceAgentLogSourceExternal},
@ -125,7 +126,7 @@ func TestInsertWorkspaceAgentLogs(t *testing.T) {
_, err = db.InsertWorkspaceAgentLogs(ctx, database.InsertWorkspaceAgentLogsParams{ _, err = db.InsertWorkspaceAgentLogs(ctx, database.InsertWorkspaceAgentLogsParams{
AgentID: agent.ID, AgentID: agent.ID,
CreatedAt: []time.Time{database.Now()}, CreatedAt: []time.Time{dbtime.Now()},
Output: []string{"second"}, Output: []string{"second"},
Level: []database.LogLevel{database.LogLevelInfo}, Level: []database.LogLevel{database.LogLevelInfo},
Source: []database.WorkspaceAgentLogSource{database.WorkspaceAgentLogSourceExternal}, Source: []database.WorkspaceAgentLogSource{database.WorkspaceAgentLogSourceExternal},
@ -360,7 +361,7 @@ func TestQueuePosition(t *testing.T) {
job, err := db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{ job, err := db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{
StartedAt: sql.NullTime{ StartedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
Types: database.AllProvisionerTypeValues(), Types: database.AllProvisionerTypeValues(),
@ -402,7 +403,7 @@ func TestUserLastSeenFilter(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
db := database.New(sqlDB) db := database.New(sqlDB)
ctx := context.Background() ctx := context.Background()
now := database.Now() now := dbtime.Now()
yesterday := dbgen.User(t, db, database.User{ yesterday := dbgen.User(t, db, database.User{
LastSeenAt: now.Add(time.Hour * -25), LastSeenAt: now.Add(time.Hour * -25),

View File

@ -79,14 +79,3 @@ func (m *StringMap) Scan(src interface{}) error {
func (m StringMap) Value() (driver.Value, error) { func (m StringMap) Value() (driver.Value, error) {
return json.Marshal(m) return json.Marshal(m)
} }
// Now returns a standardized timezone used for database resources.
func Now() time.Time {
return Time(time.Now().UTC())
}
// Time returns a time compatible with Postgres. Postgres only stores dates with
// microsecond precision.
func Time(t time.Time) time.Time {
return t.Round(time.Microsecond)
}

View File

@ -13,6 +13,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -82,7 +83,7 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
ID: id, ID: id,
Hash: hash, Hash: hash,
CreatedBy: apiKey.UserID, CreatedBy: apiKey.UserID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Mimetype: contentType, Mimetype: contentType,
Data: data, Data: data,
}) })

View File

@ -9,6 +9,7 @@ import (
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/gitauth" "github.com/coder/coder/v2/coderd/gitauth"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
@ -124,8 +125,8 @@ func (api *API) postGitAuthDeviceByID(rw http.ResponseWriter, r *http.Request) {
_, err = api.Database.InsertGitAuthLink(ctx, database.InsertGitAuthLinkParams{ _, err = api.Database.InsertGitAuthLink(ctx, database.InsertGitAuthLinkParams{
ProviderID: config.ID, ProviderID: config.ID,
UserID: apiKey.UserID, UserID: apiKey.UserID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
OAuthAccessToken: token.AccessToken, OAuthAccessToken: token.AccessToken,
OAuthRefreshToken: token.RefreshToken, OAuthRefreshToken: token.RefreshToken,
OAuthExpiry: token.Expiry, OAuthExpiry: token.Expiry,
@ -141,7 +142,7 @@ func (api *API) postGitAuthDeviceByID(rw http.ResponseWriter, r *http.Request) {
_, err = api.Database.UpdateGitAuthLink(ctx, database.UpdateGitAuthLinkParams{ _, err = api.Database.UpdateGitAuthLink(ctx, database.UpdateGitAuthLinkParams{
ProviderID: config.ID, ProviderID: config.ID,
UserID: apiKey.UserID, UserID: apiKey.UserID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
OAuthAccessToken: token.AccessToken, OAuthAccessToken: token.AccessToken,
OAuthRefreshToken: token.RefreshToken, OAuthRefreshToken: token.RefreshToken,
OAuthExpiry: token.Expiry, OAuthExpiry: token.Expiry,
@ -212,8 +213,8 @@ func (api *API) gitAuthCallback(gitAuthConfig *gitauth.Config) http.HandlerFunc
_, err = api.Database.InsertGitAuthLink(ctx, database.InsertGitAuthLinkParams{ _, err = api.Database.InsertGitAuthLink(ctx, database.InsertGitAuthLinkParams{
ProviderID: gitAuthConfig.ID, ProviderID: gitAuthConfig.ID,
UserID: apiKey.UserID, UserID: apiKey.UserID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
OAuthAccessToken: state.Token.AccessToken, OAuthAccessToken: state.Token.AccessToken,
OAuthRefreshToken: state.Token.RefreshToken, OAuthRefreshToken: state.Token.RefreshToken,
OAuthExpiry: state.Token.Expiry, OAuthExpiry: state.Token.Expiry,
@ -229,7 +230,7 @@ func (api *API) gitAuthCallback(gitAuthConfig *gitauth.Config) http.HandlerFunc
_, err = api.Database.UpdateGitAuthLink(ctx, database.UpdateGitAuthLinkParams{ _, err = api.Database.UpdateGitAuthLink(ctx, database.UpdateGitAuthLinkParams{
ProviderID: gitAuthConfig.ID, ProviderID: gitAuthConfig.ID,
UserID: apiKey.UserID, UserID: apiKey.UserID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
OAuthAccessToken: state.Token.AccessToken, OAuthAccessToken: state.Token.AccessToken,
OAuthRefreshToken: state.Token.RefreshToken, OAuthRefreshToken: state.Token.RefreshToken,
OAuthExpiry: state.Token.Expiry, OAuthExpiry: state.Token.Expiry,

View File

@ -16,6 +16,7 @@ import (
"github.com/google/go-github/v43/github" "github.com/google/go-github/v43/github"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/retry" "github.com/coder/retry"
@ -63,7 +64,7 @@ type Config struct {
func (c *Config) RefreshToken(ctx context.Context, db database.Store, gitAuthLink database.GitAuthLink) (database.GitAuthLink, bool, error) { func (c *Config) RefreshToken(ctx context.Context, db database.Store, gitAuthLink database.GitAuthLink) (database.GitAuthLink, bool, error) {
// If the token is expired and refresh is disabled, we prompt // If the token is expired and refresh is disabled, we prompt
// the user to authenticate again. // the user to authenticate again.
if c.NoRefresh && gitAuthLink.OAuthExpiry.Before(database.Now()) { if c.NoRefresh && gitAuthLink.OAuthExpiry.Before(dbtime.Now()) {
return gitAuthLink, false, nil return gitAuthLink, false, nil
} }
@ -106,7 +107,7 @@ validate:
gitAuthLink, err = db.UpdateGitAuthLink(ctx, database.UpdateGitAuthLinkParams{ gitAuthLink, err = db.UpdateGitAuthLink(ctx, database.UpdateGitAuthLinkParams{
ProviderID: c.ID, ProviderID: c.ID,
UserID: gitAuthLink.UserID, UserID: gitAuthLink.UserID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
OAuthAccessToken: token.AccessToken, OAuthAccessToken: token.AccessToken,
OAuthRefreshToken: token.RefreshToken, OAuthRefreshToken: token.RefreshToken,
OAuthExpiry: token.Expiry, OAuthExpiry: token.Expiry,

View File

@ -12,7 +12,7 @@ import (
"golang.org/x/oauth2/github" "golang.org/x/oauth2/github"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
@ -182,7 +182,7 @@ func (c *DeviceAuth) ExchangeDeviceCode(ctx context.Context, deviceCode string)
return &oauth2.Token{ return &oauth2.Token{
AccessToken: body.AccessToken, AccessToken: body.AccessToken,
RefreshToken: body.RefreshToken, RefreshToken: body.RefreshToken,
Expiry: database.Now().Add(time.Duration(body.ExpiresIn) * time.Second), Expiry: dbtime.Now().Add(time.Duration(body.ExpiresIn) * time.Second),
}, nil }, nil
} }

View File

@ -17,7 +17,7 @@ import (
"golang.org/x/oauth2" "golang.org/x/oauth2"
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/gitauth" "github.com/coder/coder/v2/coderd/gitauth"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -371,7 +371,7 @@ func TestGitAuthCallback(t *testing.T) {
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "token", AccessToken: "token",
RefreshToken: "something", RefreshToken: "something",
Expiry: database.Now().Add(-time.Hour), Expiry: dbtime.Now().Add(-time.Hour),
}, },
}, },
ID: "github", ID: "github",

View File

@ -5,6 +5,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/gitsshkey" "github.com/coder/coder/v2/coderd/gitsshkey"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
@ -53,7 +54,7 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) {
newKey, err := api.Database.UpdateGitSSHKey(ctx, database.UpdateGitSSHKeyParams{ newKey, err := api.Database.UpdateGitSSHKey(ctx, database.UpdateGitSSHKeyParams{
UserID: user.ID, UserID: user.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
PrivateKey: privateKey, PrivateKey: privateKey,
PublicKey: publicKey, PublicKey: publicKey,
}) })

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
@ -41,7 +42,7 @@ func TestRequireAPIKeyOrWorkspaceProxyAuth(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{ _, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
}) })
r = httptest.NewRequest("GET", "/", nil) r = httptest.NewRequest("GET", "/", nil)
@ -78,7 +79,7 @@ func TestRequireAPIKeyOrWorkspaceProxyAuth(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
_, userToken = dbgen.APIKey(t, db, database.APIKey{ _, userToken = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
}) })
proxy, proxyToken = dbgen.WorkspaceProxy(t, db, database.WorkspaceProxy{}) proxy, proxyToken = dbgen.WorkspaceProxy(t, db, database.WorkspaceProxy{})

View File

@ -20,6 +20,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -236,7 +237,7 @@ func ExtractAPIKey(rw http.ResponseWriter, r *http.Request, cfg ExtractAPIKeyCon
var ( var (
link database.UserLink link database.UserLink
now = database.Now() now = dbtime.Now()
// Tracks if the API key has properties updated // Tracks if the API key has properties updated
changed = false changed = false
) )
@ -384,8 +385,8 @@ func ExtractAPIKey(rw http.ResponseWriter, r *http.Request, cfg ExtractAPIKeyCon
// nolint:gocritic // nolint:gocritic
_, err = cfg.DB.UpdateUserLastSeenAt(dbauthz.AsSystemRestricted(ctx), database.UpdateUserLastSeenAtParams{ _, err = cfg.DB.UpdateUserLastSeenAt(dbauthz.AsSystemRestricted(ctx), database.UpdateUserLastSeenAtParams{
ID: key.UserID, ID: key.UserID,
LastSeenAt: database.Now(), LastSeenAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return write(http.StatusInternalServerError, codersdk.Response{ return write(http.StatusInternalServerError, codersdk.Response{
@ -413,7 +414,7 @@ func ExtractAPIKey(rw http.ResponseWriter, r *http.Request, cfg ExtractAPIKeyCon
u, err := cfg.DB.UpdateUserStatus(dbauthz.AsSystemRestricted(ctx), database.UpdateUserStatusParams{ u, err := cfg.DB.UpdateUserStatus(dbauthz.AsSystemRestricted(ctx), database.UpdateUserStatusParams{
ID: key.UserID, ID: key.UserID,
Status: database.UserStatusActive, Status: database.UserStatusActive,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return write(http.StatusInternalServerError, codersdk.Response{ return write(http.StatusInternalServerError, codersdk.Response{

View File

@ -21,6 +21,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -213,7 +214,7 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{ sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
}) })
r = httptest.NewRequest("GET", "/", nil) r = httptest.NewRequest("GET", "/", nil)
@ -248,7 +249,7 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{ _, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
Scope: database.APIKeyScopeApplicationConnect, Scope: database.APIKeyScopeApplicationConnect,
}) })
@ -285,7 +286,7 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{ _, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
}) })
r = httptest.NewRequest("GET", "/", nil) r = httptest.NewRequest("GET", "/", nil)
@ -317,8 +318,8 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{ sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now().AddDate(0, 0, -1), LastUsed: dbtime.Now().AddDate(0, 0, -1),
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
}) })
r = httptest.NewRequest("GET", "/", nil) r = httptest.NewRequest("GET", "/", nil)
@ -348,8 +349,8 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{ sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now(), LastUsed: dbtime.Now(),
ExpiresAt: database.Now().Add(time.Minute), ExpiresAt: dbtime.Now().Add(time.Minute),
}) })
r = httptest.NewRequest("GET", "/", nil) r = httptest.NewRequest("GET", "/", nil)
@ -379,8 +380,8 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{ sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now().AddDate(0, 0, -1), LastUsed: dbtime.Now().AddDate(0, 0, -1),
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
}) })
r = httptest.NewRequest("GET", "/", nil) r = httptest.NewRequest("GET", "/", nil)
@ -411,8 +412,8 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{ sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now(), LastUsed: dbtime.Now(),
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
LoginType: database.LoginTypeGithub, LoginType: database.LoginTypeGithub,
}) })
_ = dbgen.UserLink(t, db, database.UserLink{ _ = dbgen.UserLink(t, db, database.UserLink{
@ -447,15 +448,15 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{ sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now(), LastUsed: dbtime.Now(),
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
LoginType: database.LoginTypeGithub, LoginType: database.LoginTypeGithub,
}) })
_ = dbgen.UserLink(t, db, database.UserLink{ _ = dbgen.UserLink(t, db, database.UserLink{
UserID: user.ID, UserID: user.ID,
LoginType: database.LoginTypeGithub, LoginType: database.LoginTypeGithub,
OAuthRefreshToken: "hello", OAuthRefreshToken: "hello",
OAuthExpiry: database.Now().AddDate(0, 0, -1), OAuthExpiry: dbtime.Now().AddDate(0, 0, -1),
}) })
r = httptest.NewRequest("GET", "/", nil) r = httptest.NewRequest("GET", "/", nil)
@ -466,7 +467,7 @@ func TestAPIKey(t *testing.T) {
oauthToken := &oauth2.Token{ oauthToken := &oauth2.Token{
AccessToken: "wow", AccessToken: "wow",
RefreshToken: "moo", RefreshToken: "moo",
Expiry: database.Now().AddDate(0, 0, 1), Expiry: dbtime.Now().AddDate(0, 0, 1),
} }
httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{ httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
DB: db, DB: db,
@ -495,8 +496,8 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{ sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now().AddDate(0, 0, -1), LastUsed: dbtime.Now().AddDate(0, 0, -1),
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
}) })
r = httptest.NewRequest("GET", "/", nil) r = httptest.NewRequest("GET", "/", nil)
@ -578,8 +579,8 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{ sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now(), LastUsed: dbtime.Now(),
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
LoginType: database.LoginTypeToken, LoginType: database.LoginTypeToken,
}) })
@ -611,8 +612,8 @@ func TestAPIKey(t *testing.T) {
user = dbgen.User(t, db, database.User{}) user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{ _, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now(), LastUsed: dbtime.Now(),
ExpiresAt: database.Now().AddDate(0, 0, 1), ExpiresAt: dbtime.Now().AddDate(0, 0, 1),
LoginType: database.LoginTypeOIDC, LoginType: database.LoginTypeOIDC,
}) })
_ = dbgen.UserLink(t, db, database.UserLink{ _ = dbgen.UserLink(t, db, database.UserLink{

View File

@ -17,6 +17,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -159,7 +160,7 @@ func addUser(t *testing.T, db database.Store, roles ...string) (database.User, s
user, err = db.UpdateUserStatus(context.Background(), database.UpdateUserStatusParams{ user, err = db.UpdateUserStatus(context.Background(), database.UpdateUserStatusParams{
ID: user.ID, ID: user.ID,
Status: database.UserStatusActive, Status: database.UserStatusActive,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err) require.NoError(t, err)
@ -167,8 +168,8 @@ func addUser(t *testing.T, db database.Store, roles ...string) (database.User, s
ID: id, ID: id,
UserID: user.ID, UserID: user.ID,
HashedSecret: hashed[:], HashedSecret: hashed[:],
LastUsed: database.Now(), LastUsed: dbtime.Now(),
ExpiresAt: database.Now().Add(time.Minute), ExpiresAt: dbtime.Now().Add(time.Minute),
LoginType: database.LoginTypePassword, LoginType: database.LoginTypePassword,
Scope: database.APIKeyScopeAll, Scope: database.APIKeyScopeAll,
IPAddress: pqtype.Inet{ IPAddress: pqtype.Inet{

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
@ -113,8 +114,8 @@ func TestOrganizationParam(t *testing.T) {
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{ organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: uuid.New(), ID: uuid.New(),
Name: "test", Name: "test",
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err) require.NoError(t, err)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String()) chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())

View File

@ -18,6 +18,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/cryptorand" "github.com/coder/coder/v2/cryptorand"
@ -42,8 +43,8 @@ func TestWorkspaceParam(t *testing.T) {
Email: "testaccount@coder.com", Email: "testaccount@coder.com",
HashedPassword: hashed[:], HashedPassword: hashed[:],
Username: username, Username: username,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
LoginType: database.LoginTypePassword, LoginType: database.LoginTypePassword,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -51,7 +52,7 @@ func TestWorkspaceParam(t *testing.T) {
user, err = db.UpdateUserStatus(context.Background(), database.UpdateUserStatusParams{ user, err = db.UpdateUserStatus(context.Background(), database.UpdateUserStatusParams{
ID: user.ID, ID: user.ID,
Status: database.UserStatusActive, Status: database.UserStatusActive,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err) require.NoError(t, err)
@ -59,8 +60,8 @@ func TestWorkspaceParam(t *testing.T) {
ID: id, ID: id,
UserID: user.ID, UserID: user.ID,
HashedSecret: hashed[:], HashedSecret: hashed[:],
LastUsed: database.Now(), LastUsed: dbtime.Now(),
ExpiresAt: database.Now().Add(time.Minute), ExpiresAt: dbtime.Now().Add(time.Minute),
LoginType: database.LoginTypePassword, LoginType: database.LoginTypePassword,
Scope: database.APIKeyScopeAll, Scope: database.APIKeyScopeAll,
}) })

View File

@ -17,6 +17,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/retry" "github.com/coder/retry"
) )
@ -239,7 +240,7 @@ func (c *Cache) refreshTemplateDAUs(ctx context.Context) error {
Valid: true, Valid: true,
}, },
StartTime: sql.NullTime{ StartTime: sql.NullTime{
Time: database.Time(time.Now().AddDate(0, -30, 0)), Time: dbtime.Time(time.Now().AddDate(0, -30, 0)),
Valid: true, Valid: true,
}, },
}) })
@ -256,7 +257,7 @@ func (c *Cache) refreshTemplateDAUs(ctx context.Context) error {
} }
func (c *Cache) refreshDeploymentStats(ctx context.Context) error { func (c *Cache) refreshDeploymentStats(ctx context.Context) error {
from := database.Now().Add(-15 * time.Minute) from := dbtime.Now().Add(-15 * time.Minute)
agentStats, err := c.database.GetDeploymentWorkspaceAgentStats(ctx, from) agentStats, err := c.database.GetDeploymentWorkspaceAgentStats(ctx, from)
if err != nil { if err != nil {
return err return err
@ -267,8 +268,8 @@ func (c *Cache) refreshDeploymentStats(ctx context.Context) error {
} }
c.deploymentStatsResponse.Store(&codersdk.DeploymentStats{ c.deploymentStatsResponse.Store(&codersdk.DeploymentStats{
AggregatedFrom: from, AggregatedFrom: from,
CollectedAt: database.Now(), CollectedAt: dbtime.Now(),
NextUpdateAt: database.Now().Add(c.intervals.DeploymentStats), NextUpdateAt: dbtime.Now().Add(c.intervals.DeploymentStats),
Workspaces: codersdk.WorkspaceDeploymentStats{ Workspaces: codersdk.WorkspaceDeploymentStats{
Pending: workspaceStats.PendingWorkspaces, Pending: workspaceStats.PendingWorkspaces,
Building: workspaceStats.BuildingWorkspaces, Building: workspaceStats.BuildingWorkspaces,

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/metricscache" "github.com/coder/coder/v2/coderd/metricscache"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
@ -444,7 +445,7 @@ func TestCache_DeploymentStats(t *testing.T) {
_, err := db.InsertWorkspaceAgentStat(context.Background(), database.InsertWorkspaceAgentStatParams{ _, err := db.InsertWorkspaceAgentStat(context.Background(), database.InsertWorkspaceAgentStatParams{
ID: uuid.New(), ID: uuid.New(),
AgentID: uuid.New(), AgentID: uuid.New(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
ConnectionCount: 1, ConnectionCount: 1,
RxBytes: 1, RxBytes: 1,
TxBytes: 1, TxBytes: 1,

View File

@ -10,6 +10,7 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -69,8 +70,8 @@ func (api *API) postOrganizations(rw http.ResponseWriter, r *http.Request) {
organization, err = tx.InsertOrganization(ctx, database.InsertOrganizationParams{ organization, err = tx.InsertOrganization(ctx, database.InsertOrganizationParams{
ID: uuid.New(), ID: uuid.New(),
Name: req.Name, Name: req.Name,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return xerrors.Errorf("create organization: %w", err) return xerrors.Errorf("create organization: %w", err)
@ -78,8 +79,8 @@ func (api *API) postOrganizations(rw http.ResponseWriter, r *http.Request) {
_, err = tx.InsertOrganizationMember(ctx, database.InsertOrganizationMemberParams{ _, err = tx.InsertOrganizationMember(ctx, database.InsertOrganizationMemberParams{
OrganizationID: organization.ID, OrganizationID: organization.ID,
UserID: apiKey.UserID, UserID: apiKey.UserID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Roles: []string{ Roles: []string{
// TODO: When organizations are allowed to be created, we should // TODO: When organizations are allowed to be created, we should
// come back to determining the default role of the person who // come back to determining the default role of the person who

View File

@ -18,6 +18,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/tailnet" "github.com/coder/coder/v2/tailnet"
) )
@ -57,7 +58,7 @@ func ActiveUsers(ctx context.Context, registerer prometheus.Registerer, db datab
case <-ticker.C: case <-ticker.C:
} }
apiKeys, err := db.GetAPIKeysLastUsedAfter(ctx, database.Now().Add(-1*time.Hour)) apiKeys, err := db.GetAPIKeysLastUsedAfter(ctx, dbtime.Now().Add(-1*time.Hour))
if err != nil { if err != nil {
continue continue
} }

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/coderd/batchstats" "github.com/coder/coder/v2/coderd/batchstats"
"github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@ -55,7 +56,7 @@ func TestActiveUsers(t *testing.T) {
Database: func(t *testing.T) database.Store { Database: func(t *testing.T) database.Store {
db := dbfake.New() db := dbfake.New()
dbgen.APIKey(t, db, database.APIKey{ dbgen.APIKey(t, db, database.APIKey{
LastUsed: database.Now(), LastUsed: dbtime.Now(),
}) })
return db return db
}, },
@ -66,13 +67,13 @@ func TestActiveUsers(t *testing.T) {
db := dbfake.New() db := dbfake.New()
dbgen.APIKey(t, db, database.APIKey{ dbgen.APIKey(t, db, database.APIKey{
LastUsed: database.Now(), LastUsed: dbtime.Now(),
}) })
// Because this API key hasn't been used in the past hour, this shouldn't // Because this API key hasn't been used in the past hour, this shouldn't
// add to the user count. // add to the user count.
dbgen.APIKey(t, db, database.APIKey{ dbgen.APIKey(t, db, database.APIKey{
LastUsed: database.Now().Add(-2 * time.Hour), LastUsed: dbtime.Now().Add(-2 * time.Hour),
}) })
return db return db
}, },
@ -82,10 +83,10 @@ func TestActiveUsers(t *testing.T) {
Database: func(t *testing.T) database.Store { Database: func(t *testing.T) database.Store {
db := dbfake.New() db := dbfake.New()
dbgen.APIKey(t, db, database.APIKey{ dbgen.APIKey(t, db, database.APIKey{
LastUsed: database.Now(), LastUsed: dbtime.Now(),
}) })
dbgen.APIKey(t, db, database.APIKey{ dbgen.APIKey(t, db, database.APIKey{
LastUsed: database.Now(), LastUsed: dbtime.Now(),
}) })
return db return db
}, },
@ -115,8 +116,8 @@ func TestWorkspaces(t *testing.T) {
insertRunning := func(db database.Store) database.ProvisionerJob { insertRunning := func(db database.Store) database.ProvisionerJob {
job, err := db.InsertProvisionerJob(context.Background(), database.InsertProvisionerJobParams{ job, err := db.InsertProvisionerJob(context.Background(), database.InsertProvisionerJobParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Provisioner: database.ProvisionerTypeEcho, Provisioner: database.ProvisionerTypeEcho,
StorageMethod: database.ProvisionerStorageMethodFile, StorageMethod: database.ProvisionerStorageMethodFile,
Type: database.ProvisionerJobTypeWorkspaceBuild, Type: database.ProvisionerJobTypeWorkspaceBuild,
@ -134,7 +135,7 @@ func TestWorkspaces(t *testing.T) {
// This marks the job as started. // This marks the job as started.
_, err = db.AcquireProvisionerJob(context.Background(), database.AcquireProvisionerJobParams{ _, err = db.AcquireProvisionerJob(context.Background(), database.AcquireProvisionerJobParams{
StartedAt: sql.NullTime{ StartedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
Types: []database.ProvisionerType{database.ProvisionerTypeEcho}, Types: []database.ProvisionerType{database.ProvisionerTypeEcho},
@ -148,7 +149,7 @@ func TestWorkspaces(t *testing.T) {
err := db.UpdateProvisionerJobWithCancelByID(context.Background(), database.UpdateProvisionerJobWithCancelByIDParams{ err := db.UpdateProvisionerJobWithCancelByID(context.Background(), database.UpdateProvisionerJobWithCancelByIDParams{
ID: job.ID, ID: job.ID,
CanceledAt: sql.NullTime{ CanceledAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
}) })
@ -156,7 +157,7 @@ func TestWorkspaces(t *testing.T) {
err = db.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{ err = db.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{
ID: job.ID, ID: job.ID,
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
}) })
@ -168,7 +169,7 @@ func TestWorkspaces(t *testing.T) {
err := db.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{ err := db.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{
ID: job.ID, ID: job.ID,
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
Error: sql.NullString{ Error: sql.NullString{
@ -184,7 +185,7 @@ func TestWorkspaces(t *testing.T) {
err := db.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{ err := db.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{
ID: job.ID, ID: job.ID,
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
}) })

View File

@ -30,6 +30,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub" "github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/coder/coder/v2/coderd/gitauth" "github.com/coder/coder/v2/coderd/gitauth"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
@ -138,9 +139,9 @@ func NewServer(
// calculations regarding workspace start and stop time. // calculations regarding workspace start and stop time.
func (s *server) timeNow() time.Time { func (s *server) timeNow() time.Time {
if s.TimeNowFn != nil { if s.TimeNowFn != nil {
return database.Time(s.TimeNowFn()) return dbtime.Time(s.TimeNowFn())
} }
return database.Now() return dbtime.Now()
} }
// AcquireJob queries the database to lock a job. // AcquireJob queries the database to lock a job.
@ -162,7 +163,7 @@ func (s *server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Acquire
// This marks the job as locked in the database. // This marks the job as locked in the database.
job, err := s.Database.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{ job, err := s.Database.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{
StartedAt: sql.NullTime{ StartedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
WorkerID: uuid.NullUUID{ WorkerID: uuid.NullUUID{
@ -176,7 +177,7 @@ func (s *server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Acquire
// The provisioner daemon assumes no jobs are available if // The provisioner daemon assumes no jobs are available if
// an empty struct is returned. // an empty struct is returned.
lastAcquireMutex.Lock() lastAcquireMutex.Lock()
lastAcquire = database.Now() lastAcquire = dbtime.Now()
lastAcquireMutex.Unlock() lastAcquireMutex.Unlock()
return &proto.AcquiredJob{}, nil return &proto.AcquiredJob{}, nil
} }
@ -190,7 +191,7 @@ func (s *server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Acquire
err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: job.ID, ID: job.ID,
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
Error: sql.NullString{ Error: sql.NullString{
@ -533,7 +534,7 @@ func (s *server) UpdateJob(ctx context.Context, request *proto.UpdateJobRequest)
} }
err = s.Database.UpdateProvisionerJobByID(ctx, database.UpdateProvisionerJobByIDParams{ err = s.Database.UpdateProvisionerJobByID(ctx, database.UpdateProvisionerJobByIDParams{
ID: parsedID, ID: parsedID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return nil, xerrors.Errorf("update job: %w", err) return nil, xerrors.Errorf("update job: %w", err)
@ -590,7 +591,7 @@ func (s *server) UpdateJob(ctx context.Context, request *proto.UpdateJobRequest)
err := s.Database.UpdateTemplateVersionDescriptionByJobID(ctx, database.UpdateTemplateVersionDescriptionByJobIDParams{ err := s.Database.UpdateTemplateVersionDescriptionByJobID(ctx, database.UpdateTemplateVersionDescriptionByJobIDParams{
JobID: job.ID, JobID: job.ID,
Readme: string(request.Readme), Readme: string(request.Readme),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return nil, xerrors.Errorf("update template version description: %w", err) return nil, xerrors.Errorf("update template version description: %w", err)
@ -679,7 +680,7 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
return nil, xerrors.Errorf("job already completed") return nil, xerrors.Errorf("job already completed")
} }
job.CompletedAt = sql.NullTime{ job.CompletedAt = sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
} }
job.Error = sql.NullString{ job.Error = sql.NullString{
@ -694,7 +695,7 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: jobID, ID: jobID,
CompletedAt: job.CompletedAt, CompletedAt: job.CompletedAt,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Error: job.Error, Error: job.Error,
ErrorCode: job.ErrorCode, ErrorCode: job.ErrorCode,
}) })
@ -723,7 +724,7 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
if jobType.WorkspaceBuild.State != nil { if jobType.WorkspaceBuild.State != nil {
err = db.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{ err = db.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{
ID: input.WorkspaceBuildID, ID: input.WorkspaceBuildID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
ProvisionerState: jobType.WorkspaceBuild.State, ProvisionerState: jobType.WorkspaceBuild.State,
Deadline: build.Deadline, Deadline: build.Deadline,
MaxDeadline: build.MaxDeadline, MaxDeadline: build.MaxDeadline,
@ -929,7 +930,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
err = s.Database.UpdateTemplateVersionGitAuthProvidersByJobID(ctx, database.UpdateTemplateVersionGitAuthProvidersByJobIDParams{ err = s.Database.UpdateTemplateVersionGitAuthProvidersByJobID(ctx, database.UpdateTemplateVersionGitAuthProvidersByJobIDParams{
JobID: jobID, JobID: jobID,
GitAuthProviders: jobType.TemplateImport.GitAuthProviders, GitAuthProviders: jobType.TemplateImport.GitAuthProviders,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return nil, xerrors.Errorf("update template version git auth providers: %w", err) return nil, xerrors.Errorf("update template version git auth providers: %w", err)
@ -937,9 +938,9 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: jobID, ID: jobID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
Error: completedError, Error: completedError,
@ -994,9 +995,9 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
err = db.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ err = db.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: jobID, ID: jobID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
}) })
@ -1044,7 +1045,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
slog.F("workspace_build_id", workspaceBuild.ID), slog.F("workspace_build_id", workspaceBuild.ID),
slog.F("timeout", d), slog.F("timeout", d),
) )
// Agents are inserted with `database.Now()`, this triggers a // Agents are inserted with `dbtime.Now()`, this triggers a
// workspace event approximately after created + timeout seconds. // workspace event approximately after created + timeout seconds.
updates = append(updates, time.After(d)) updates = append(updates, time.After(d))
} }
@ -1143,9 +1144,9 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: jobID, ID: jobID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
}) })
@ -1188,7 +1189,7 @@ func (s *server) startTrace(ctx context.Context, name string, opts ...trace.Span
func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.UUID, transition database.WorkspaceTransition, protoResource *sdkproto.Resource, snapshot *telemetry.Snapshot) error { func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.UUID, transition database.WorkspaceTransition, protoResource *sdkproto.Resource, snapshot *telemetry.Snapshot) error {
resource, err := db.InsertWorkspaceResource(ctx, database.InsertWorkspaceResourceParams{ resource, err := db.InsertWorkspaceResource(ctx, database.InsertWorkspaceResourceParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
JobID: jobID, JobID: jobID,
Transition: transition, Transition: transition,
Type: protoResource.Type, Type: protoResource.Type,
@ -1250,8 +1251,8 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
agentID := uuid.New() agentID := uuid.New()
dbAgent, err := db.InsertWorkspaceAgent(ctx, database.InsertWorkspaceAgentParams{ dbAgent, err := db.InsertWorkspaceAgent(ctx, database.InsertWorkspaceAgentParams{
ID: agentID, ID: agentID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
ResourceID: resource.ID, ResourceID: resource.ID,
Name: prAgent.Name, Name: prAgent.Name,
AuthToken: authToken, AuthToken: authToken,
@ -1327,7 +1328,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
dbApp, err := db.InsertWorkspaceApp(ctx, database.InsertWorkspaceAppParams{ dbApp, err := db.InsertWorkspaceApp(ctx, database.InsertWorkspaceAppParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
AgentID: dbAgent.ID, AgentID: dbAgent.ID,
Slug: slug, Slug: slug,
DisplayName: app.DisplayName, DisplayName: app.DisplayName,
@ -1449,7 +1450,7 @@ func obtainOIDCAccessToken(ctx context.Context, db database.Store, oidcConfig ht
return "", xerrors.Errorf("get owner oidc link: %w", err) return "", xerrors.Errorf("get owner oidc link: %w", err)
} }
if link.OAuthExpiry.Before(database.Now()) && !link.OAuthExpiry.IsZero() && link.OAuthRefreshToken != "" { if link.OAuthExpiry.Before(dbtime.Now()) && !link.OAuthExpiry.IsZero() && link.OAuthRefreshToken != "" {
token, err := oidcConfig.TokenSource(ctx, &oauth2.Token{ token, err := oidcConfig.TokenSource(ctx, &oauth2.Token{
AccessToken: link.OAuthAccessToken, AccessToken: link.OAuthAccessToken,
RefreshToken: link.OAuthRefreshToken, RefreshToken: link.OAuthRefreshToken,

View File

@ -12,6 +12,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
) )
@ -32,7 +33,7 @@ func TestObtainOIDCAccessToken(t *testing.T) {
dbgen.UserLink(t, db, database.UserLink{ dbgen.UserLink(t, db, database.UserLink{
UserID: user.ID, UserID: user.ID,
LoginType: database.LoginTypeOIDC, LoginType: database.LoginTypeOIDC,
OAuthExpiry: database.Now().Add(-time.Hour), OAuthExpiry: dbtime.Now().Add(-time.Hour),
}) })
_, err := obtainOIDCAccessToken(ctx, db, &oauth2.Config{}, user.ID) _, err := obtainOIDCAccessToken(ctx, db, &oauth2.Config{}, user.ID)
require.NoError(t, err) require.NoError(t, err)
@ -44,7 +45,7 @@ func TestObtainOIDCAccessToken(t *testing.T) {
dbgen.UserLink(t, db, database.UserLink{ dbgen.UserLink(t, db, database.UserLink{
UserID: user.ID, UserID: user.ID,
LoginType: database.LoginTypeOIDC, LoginType: database.LoginTypeOIDC,
OAuthExpiry: database.Now().Add(-time.Hour), OAuthExpiry: dbtime.Now().Add(-time.Hour),
}) })
_, err := obtainOIDCAccessToken(ctx, db, &testutil.OAuth2Config{ _, err := obtainOIDCAccessToken(ctx, db, &testutil.OAuth2Config{
Token: &oauth2.Token{ Token: &oauth2.Token{

View File

@ -22,6 +22,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub" "github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/coder/coder/v2/coderd/gitauth" "github.com/coder/coder/v2/coderd/gitauth"
"github.com/coder/coder/v2/coderd/provisionerdserver" "github.com/coder/coder/v2/coderd/provisionerdserver"
@ -136,7 +137,7 @@ func TestAcquireJob(t *testing.T) {
link := dbgen.UserLink(t, db, database.UserLink{ link := dbgen.UserLink(t, db, database.UserLink{
LoginType: database.LoginTypeOIDC, LoginType: database.LoginTypeOIDC,
UserID: user.ID, UserID: user.ID,
OAuthExpiry: database.Now().Add(time.Hour), OAuthExpiry: dbtime.Now().Add(time.Hour),
OAuthAccessToken: "access-token", OAuthAccessToken: "access-token",
}) })
dbgen.GitAuthLink(t, db, database.GitAuthLink{ dbgen.GitAuthLink(t, db, database.GitAuthLink{
@ -159,7 +160,7 @@ func TestAcquireJob(t *testing.T) {
err := db.UpdateTemplateVersionGitAuthProvidersByJobID(ctx, database.UpdateTemplateVersionGitAuthProvidersByJobIDParams{ err := db.UpdateTemplateVersionGitAuthProvidersByJobID(ctx, database.UpdateTemplateVersionGitAuthProvidersByJobIDParams{
JobID: version.JobID, JobID: version.JobID,
GitAuthProviders: []string{gitAuthProvider}, GitAuthProviders: []string{gitAuthProvider},
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err) require.NoError(t, err)
// Import version job // Import version job
@ -743,7 +744,7 @@ func TestFailJob(t *testing.T) {
err = db.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ err = db.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: job.ID, ID: job.ID,
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
}) })
@ -1108,7 +1109,7 @@ func TestCompleteJob(t *testing.T) {
}) })
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AllowUserAutostart: c.templateAllowAutostop, AllowUserAutostart: c.templateAllowAutostop,
DefaultTTL: int64(c.templateDefaultTTL), DefaultTTL: int64(c.templateDefaultTTL),
MaxTTL: int64(c.templateMaxTTL), MaxTTL: int64(c.templateMaxTTL),
@ -1351,7 +1352,7 @@ func TestCompleteJob(t *testing.T) {
}) })
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AllowUserAutostart: false, AllowUserAutostart: false,
AllowUserAutostop: true, AllowUserAutostop: true,
DefaultTTL: 0, DefaultTTL: 0,

View File

@ -20,6 +20,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbmock" "github.com/coder/coder/v2/coderd/database/dbmock"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub" "github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/provisionersdk" "github.com/coder/coder/v2/provisionersdk"
@ -29,7 +30,7 @@ import (
func TestConvertProvisionerJob_Unit(t *testing.T) { func TestConvertProvisionerJob_Unit(t *testing.T) {
t.Parallel() t.Parallel()
validNullTimeMock := sql.NullTime{ validNullTimeMock := sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
} }
invalidNullTimeMock := sql.NullTime{} invalidNullTimeMock := sql.NullTime{}
@ -142,7 +143,7 @@ func Test_logFollower_completeBeforeFollow(t *testing.T) {
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
mDB := dbmock.NewMockStore(ctrl) mDB := dbmock.NewMockStore(ctrl)
ps := pubsub.NewInMemory() ps := pubsub.NewInMemory()
now := database.Now() now := dbtime.Now()
job := database.ProvisionerJob{ job := database.ProvisionerJob{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: now.Add(-10 * time.Second), CreatedAt: now.Add(-10 * time.Second),
@ -204,7 +205,7 @@ func Test_logFollower_completeBeforeSubscribe(t *testing.T) {
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
mDB := dbmock.NewMockStore(ctrl) mDB := dbmock.NewMockStore(ctrl)
ps := pubsub.NewInMemory() ps := pubsub.NewInMemory()
now := database.Now() now := dbtime.Now()
job := database.ProvisionerJob{ job := database.ProvisionerJob{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: now.Add(-10 * time.Second), CreatedAt: now.Add(-10 * time.Second),
@ -280,7 +281,7 @@ func Test_logFollower_EndOfLogs(t *testing.T) {
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
mDB := dbmock.NewMockStore(ctrl) mDB := dbmock.NewMockStore(ctrl)
ps := pubsub.NewInMemory() ps := pubsub.NewInMemory()
now := database.Now() now := dbtime.Now()
job := database.ProvisionerJob{ job := database.ProvisionerJob{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: now.Add(-10 * time.Second), CreatedAt: now.Add(-10 * time.Second),

View File

@ -14,6 +14,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/schedule" "github.com/coder/coder/v2/coderd/schedule"
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
) )
@ -455,7 +456,7 @@ func TestCalculateAutoStop(t *testing.T) {
}) })
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AllowUserAutostart: c.templateAllowAutostop, AllowUserAutostart: c.templateAllowAutostop,
AutostopRequirementDaysOfWeek: int16(c.templateAutostopRequirement.DaysOfWeek), AutostopRequirementDaysOfWeek: int16(c.templateAutostopRequirement.DaysOfWeek),
AutostopRequirementWeeks: c.templateAutostopRequirement.Weeks, AutostopRequirementWeeks: c.templateAutostopRequirement.Weeks,

View File

@ -8,6 +8,7 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/tracing" "github.com/coder/coder/v2/coderd/tracing"
) )
@ -178,7 +179,7 @@ func (*agplTemplateScheduleStore) Set(ctx context.Context, db database.Store, tp
err := db.InTx(func(db database.Store) error { err := db.InTx(func(db database.Store) error {
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: tpl.ID, ID: tpl.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
DefaultTTL: int64(opts.DefaultTTL), DefaultTTL: int64(opts.DefaultTTL),
// Don't allow changing these settings, but keep the value in the DB (to // Don't allow changing these settings, but keep the value in the DB (to
// avoid clearing settings if the license has an issue). // avoid clearing settings if the license has an issue).

View File

@ -24,6 +24,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/buildinfo" "github.com/coder/coder/v2/buildinfo"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
) )
const ( const (
@ -77,7 +78,7 @@ func New(options Options) (Reporter, error) {
options: options, options: options,
deploymentURL: deploymentURL, deploymentURL: deploymentURL,
snapshotURL: snapshotURL, snapshotURL: snapshotURL,
startedAt: database.Now(), startedAt: dbtime.Now(),
} }
go reporter.runSnapshotter() go reporter.runSnapshotter()
return reporter, nil return reporter, nil
@ -150,7 +151,7 @@ func (r *remoteReporter) Close() {
return return
} }
close(r.closed) close(r.closed)
now := database.Now() now := dbtime.Now()
r.shutdownAt = &now r.shutdownAt = &now
// Report a final collection of telemetry prior to close! // Report a final collection of telemetry prior to close!
// This could indicate final actions a user has taken, and // This could indicate final actions a user has taken, and
@ -289,7 +290,7 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
ctx = r.ctx ctx = r.ctx
// For resources that grow in size very quickly (like workspace builds), // For resources that grow in size very quickly (like workspace builds),
// we only report events that occurred within the past hour. // we only report events that occurred within the past hour.
createdAfter = database.Now().Add(-1 * time.Hour) createdAfter = dbtime.Now().Add(-1 * time.Hour)
eg errgroup.Group eg errgroup.Group
snapshot = &Snapshot{ snapshot = &Snapshot{
DeploymentID: r.options.DeploymentID, DeploymentID: r.options.DeploymentID,

View File

@ -20,6 +20,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/telemetry" "github.com/coder/coder/v2/coderd/telemetry"
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
) )
@ -76,9 +77,9 @@ func TestTelemetry(t *testing.T) {
}) })
_ = dbgen.WorkspaceAgentStat(t, db, database.WorkspaceAgentStat{}) _ = dbgen.WorkspaceAgentStat(t, db, database.WorkspaceAgentStat{})
_, err = db.InsertLicense(ctx, database.InsertLicenseParams{ _, err = db.InsertLicense(ctx, database.InsertLicenseParams{
UploadedAt: database.Now(), UploadedAt: dbtime.Now(),
JWT: "", JWT: "",
Exp: database.Now().Add(time.Hour), Exp: dbtime.Now().Add(time.Hour),
UUID: uuid.New(), UUID: uuid.New(),
}) })
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -87,7 +88,7 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) {
err = api.Database.UpdateTemplateDeletedByID(ctx, database.UpdateTemplateDeletedByIDParams{ err = api.Database.UpdateTemplateDeletedByID(ctx, database.UpdateTemplateDeletedByIDParams{
ID: template.ID, ID: template.ID,
Deleted: true, Deleted: true,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
@ -301,7 +302,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
defaultsGroups[organization.ID.String()] = []rbac.Action{rbac.ActionRead} defaultsGroups[organization.ID.String()] = []rbac.Action{rbac.ActionRead}
} }
err = api.Database.InTx(func(tx database.Store) error { err = api.Database.InTx(func(tx database.Store) error {
now := database.Now() now := dbtime.Now()
id := uuid.New() id := uuid.New()
err = tx.InsertTemplate(ctx, database.InsertTemplateParams{ err = tx.InsertTemplate(ctx, database.InsertTemplateParams{
ID: id, ID: id,
@ -356,7 +357,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
UUID: dbTemplate.ID, UUID: dbTemplate.ID,
Valid: true, Valid: true,
}, },
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Name: templateVersion.Name, Name: templateVersion.Name,
Message: templateVersion.Message, Message: templateVersion.Message,
}) })
@ -585,7 +586,7 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
var err error var err error
err = tx.UpdateTemplateMetaByID(ctx, database.UpdateTemplateMetaByIDParams{ err = tx.UpdateTemplateMetaByID(ctx, database.UpdateTemplateMetaByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Name: name, Name: name,
DisplayName: req.DisplayName, DisplayName: req.DisplayName,
Description: req.Description, Description: req.Description,

View File

@ -16,6 +16,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/schedule" "github.com/coder/coder/v2/coderd/schedule"
"github.com/coder/coder/v2/coderd/util/ptr" "github.com/coder/coder/v2/coderd/util/ptr"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -262,7 +263,7 @@ func TestPostTemplateByOrganization(t *testing.T) {
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AllowUserAutostart: options.UserAutostartEnabled, AllowUserAutostart: options.UserAutostartEnabled,
AllowUserAutostop: options.UserAutostopEnabled, AllowUserAutostop: options.UserAutostopEnabled,
DefaultTTL: int64(options.DefaultTTL), DefaultTTL: int64(options.DefaultTTL),
@ -312,7 +313,7 @@ func TestPostTemplateByOrganization(t *testing.T) {
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AllowUserAutostart: options.UserAutostartEnabled, AllowUserAutostart: options.UserAutostartEnabled,
AllowUserAutostop: options.UserAutostopEnabled, AllowUserAutostop: options.UserAutostopEnabled,
DefaultTTL: int64(options.DefaultTTL), DefaultTTL: int64(options.DefaultTTL),
@ -590,7 +591,7 @@ func TestPatchTemplateMeta(t *testing.T) {
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AllowUserAutostart: options.UserAutostartEnabled, AllowUserAutostart: options.UserAutostartEnabled,
AllowUserAutostop: options.UserAutostopEnabled, AllowUserAutostop: options.UserAutostopEnabled,
DefaultTTL: int64(options.DefaultTTL), DefaultTTL: int64(options.DefaultTTL),
@ -981,7 +982,7 @@ func TestPatchTemplateMeta(t *testing.T) {
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AllowUserAutostart: options.UserAutostartEnabled, AllowUserAutostart: options.UserAutostartEnabled,
AllowUserAutostop: options.UserAutostopEnabled, AllowUserAutostop: options.UserAutostopEnabled,
DefaultTTL: int64(options.DefaultTTL), DefaultTTL: int64(options.DefaultTTL),
@ -1050,7 +1051,7 @@ func TestPatchTemplateMeta(t *testing.T) {
err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{ err := db.UpdateTemplateScheduleByID(ctx, database.UpdateTemplateScheduleByIDParams{
ID: template.ID, ID: template.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AllowUserAutostart: options.UserAutostartEnabled, AllowUserAutostart: options.UserAutostartEnabled,
AllowUserAutostop: options.UserAutostopEnabled, AllowUserAutostop: options.UserAutostopEnabled,
DefaultTTL: int64(options.DefaultTTL), DefaultTTL: int64(options.DefaultTTL),
@ -1288,6 +1289,6 @@ func TestTemplateMetrics(t *testing.T) {
res, err = client.Workspaces(ctx, codersdk.WorkspaceFilter{}) res, err = client.Workspaces(ctx, codersdk.WorkspaceFilter{})
require.NoError(t, err) require.NoError(t, err)
assert.WithinDuration(t, assert.WithinDuration(t,
database.Now(), res.Workspaces[0].LastUsedAt, time.Minute, dbtime.Now(), res.Workspaces[0].LastUsedAt, time.Minute,
) )
} }

View File

@ -20,6 +20,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/gitauth" "github.com/coder/coder/v2/coderd/gitauth"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
@ -95,7 +96,7 @@ func (api *API) patchTemplateVersion(rw http.ResponseWriter, r *http.Request) {
updateParams := database.UpdateTemplateVersionByIDParams{ updateParams := database.UpdateTemplateVersionByIDParams{
ID: templateVersion.ID, ID: templateVersion.ID,
TemplateID: templateVersion.TemplateID, TemplateID: templateVersion.TemplateID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Name: templateVersion.Name, Name: templateVersion.Name,
Message: templateVersion.Message, Message: templateVersion.Message,
} }
@ -204,11 +205,11 @@ func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Reque
err = api.Database.UpdateProvisionerJobWithCancelByID(ctx, database.UpdateProvisionerJobWithCancelByIDParams{ err = api.Database.UpdateProvisionerJobWithCancelByID(ctx, database.UpdateProvisionerJobWithCancelByIDParams{
ID: job.ID, ID: job.ID,
CanceledAt: sql.NullTime{ CanceledAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
// If the job is running, don't mark it completed! // If the job is running, don't mark it completed!
Valid: !job.WorkerID.Valid, Valid: !job.WorkerID.Valid,
}, },
@ -478,8 +479,8 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques
jobID := uuid.New() jobID := uuid.New()
provisionerJob, err := api.Database.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ provisionerJob, err := api.Database.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
ID: jobID, ID: jobID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
OrganizationID: templateVersion.OrganizationID, OrganizationID: templateVersion.OrganizationID,
InitiatorID: apiKey.UserID, InitiatorID: apiKey.UserID,
Provisioner: job.Provisioner, Provisioner: job.Provisioner,
@ -605,11 +606,11 @@ func (api *API) patchTemplateVersionDryRunCancel(rw http.ResponseWriter, r *http
err := api.Database.UpdateProvisionerJobWithCancelByID(ctx, database.UpdateProvisionerJobWithCancelByIDParams{ err := api.Database.UpdateProvisionerJobWithCancelByID(ctx, database.UpdateProvisionerJobWithCancelByIDParams{
ID: job.ProvisionerJob.ID, ID: job.ProvisionerJob.ID,
CanceledAt: sql.NullTime{ CanceledAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
// If the job is running, don't mark it completed! // If the job is running, don't mark it completed!
Valid: !job.ProvisionerJob.WorkerID.Valid, Valid: !job.ProvisionerJob.WorkerID.Valid,
}, },
@ -1036,7 +1037,7 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque
err = store.UpdateTemplateActiveVersionByID(ctx, database.UpdateTemplateActiveVersionByIDParams{ err = store.UpdateTemplateActiveVersionByID(ctx, database.UpdateTemplateActiveVersionByIDParams{
ID: template.ID, ID: template.ID,
ActiveVersionID: req.ID, ActiveVersionID: req.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return xerrors.Errorf("update active version: %w", err) return xerrors.Errorf("update active version: %w", err)
@ -1174,7 +1175,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
ID: uuid.New(), ID: uuid.New(),
Hash: hash, Hash: hash,
CreatedBy: apiKey.UserID, CreatedBy: apiKey.UserID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Mimetype: tarMimeType, Mimetype: tarMimeType,
Data: tar, Data: tar,
}) })
@ -1227,8 +1228,8 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
provisionerJob, err = tx.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ provisionerJob, err = tx.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
ID: jobID, ID: jobID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
OrganizationID: organization.ID, OrganizationID: organization.ID,
InitiatorID: apiKey.UserID, InitiatorID: apiKey.UserID,
Provisioner: database.ProvisionerType(req.Provisioner), Provisioner: database.ProvisionerType(req.Provisioner),
@ -1262,8 +1263,8 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
ID: templateVersionID, ID: templateVersionID,
TemplateID: templateID, TemplateID: templateID,
OrganizationID: organization.ID, OrganizationID: organization.ID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Name: req.Name, Name: req.Name,
Message: req.Message, Message: req.Message,
Readme: "", Readme: "",

View File

@ -16,6 +16,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub" "github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/coder/coder/v2/provisionersdk" "github.com/coder/coder/v2/provisionersdk"
) )
@ -274,7 +275,7 @@ func unhangJob(ctx context.Context, log slog.Logger, db database.Store, pub pubs
insertParams := database.InsertProvisionerJobLogsParams{ insertParams := database.InsertProvisionerJobLogsParams{
JobID: job.ID, JobID: job.ID,
} }
now := database.Now() now := dbtime.Now()
for i, msg := range HungJobLogMessages { for i, msg := range HungJobLogMessages {
// Set the created at in a way that ensures each message has // Set the created at in a way that ensures each message has
// a unique timestamp so they will be sorted correctly. // a unique timestamp so they will be sorted correctly.
@ -291,7 +292,7 @@ func unhangJob(ctx context.Context, log slog.Logger, db database.Store, pub pubs
lowestLogID = newLogs[0].ID lowestLogID = newLogs[0].ID
// Mark the job as failed. // Mark the job as failed.
now = database.Now() now = dbtime.Now()
err = db.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ err = db.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: job.ID, ID: job.ID,
UpdatedAt: now, UpdatedAt: now,
@ -334,7 +335,7 @@ func unhangJob(ctx context.Context, log slog.Logger, db database.Store, pub pubs
if err == nil { if err == nil {
err = db.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{ err = db.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{
ID: build.ID, ID: build.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
ProvisionerState: prevBuild.ProvisionerState, ProvisionerState: prevBuild.ProvisionerState,
Deadline: time.Time{}, Deadline: time.Time{},
MaxDeadline: time.Time{}, MaxDeadline: time.Time{},

View File

@ -27,6 +27,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -328,7 +329,7 @@ func (api *API) loginRequest(ctx context.Context, rw http.ResponseWriter, req co
user, err = api.Database.UpdateUserStatus(dbauthz.AsSystemRestricted(ctx), database.UpdateUserStatusParams{ user, err = api.Database.UpdateUserStatus(dbauthz.AsSystemRestricted(ctx), database.UpdateUserStatusParams{
ID: user.ID, ID: user.ID,
Status: database.UserStatusActive, Status: database.UserStatusActive,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
logger.Error(ctx, "unable to update user status to active", slog.Error(err)) logger.Error(ctx, "unable to update user status to active", slog.Error(err))
@ -1317,7 +1318,7 @@ func (api *API) oauthLogin(r *http.Request, params *oauthLoginParams) ([]*http.C
user, err = tx.UpdateUserStatus(dbauthz.AsSystemRestricted(ctx), database.UpdateUserStatusParams{ user, err = tx.UpdateUserStatus(dbauthz.AsSystemRestricted(ctx), database.UpdateUserStatusParams{
ID: user.ID, ID: user.ID,
Status: database.UserStatusActive, Status: database.UserStatusActive,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
logger.Error(ctx, "unable to update user status to active", slog.Error(err)) logger.Error(ctx, "unable to update user status to active", slog.Error(err))
@ -1436,7 +1437,7 @@ func (api *API) oauthLogin(r *http.Request, params *oauthLoginParams) ([]*http.C
ID: user.ID, ID: user.ID,
Email: user.Email, Email: user.Email,
Username: user.Username, Username: user.Username,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
AvatarURL: user.AvatarURL, AvatarURL: user.AvatarURL,
}) })
if err != nil { if err != nil {

View File

@ -16,6 +16,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/gitsshkey" "github.com/coder/coder/v2/coderd/gitsshkey"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
@ -610,7 +611,7 @@ func (api *API) putUserProfile(rw http.ResponseWriter, r *http.Request) {
Email: user.Email, Email: user.Email,
AvatarURL: user.AvatarURL, AvatarURL: user.AvatarURL,
Username: params.Username, Username: params.Username,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
aReq.New = updatedUserProfile aReq.New = updatedUserProfile
@ -698,7 +699,7 @@ func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseW
suspendedUser, err := api.Database.UpdateUserStatus(ctx, database.UpdateUserStatusParams{ suspendedUser, err := api.Database.UpdateUserStatus(ctx, database.UpdateUserStatusParams{
ID: user.ID, ID: user.ID,
Status: status, Status: status,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
@ -1080,8 +1081,8 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
organization, err := tx.InsertOrganization(ctx, database.InsertOrganizationParams{ organization, err := tx.InsertOrganization(ctx, database.InsertOrganizationParams{
ID: uuid.New(), ID: uuid.New(),
Name: req.Username, Name: req.Username,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return xerrors.Errorf("create organization: %w", err) return xerrors.Errorf("create organization: %w", err)
@ -1103,8 +1104,8 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
ID: uuid.New(), ID: uuid.New(),
Email: req.Email, Email: req.Email,
Username: req.Username, Username: req.Username,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
// All new users are defaulted to members of the site. // All new users are defaulted to members of the site.
RBACRoles: []string{}, RBACRoles: []string{},
LoginType: req.LoginType, LoginType: req.LoginType,
@ -1130,8 +1131,8 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
} }
_, err = tx.InsertGitSSHKey(ctx, database.InsertGitSSHKeyParams{ _, err = tx.InsertGitSSHKey(ctx, database.InsertGitSSHKeyParams{
UserID: user.ID, UserID: user.ID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
PrivateKey: privateKey, PrivateKey: privateKey,
PublicKey: publicKey, PublicKey: publicKey,
}) })
@ -1141,8 +1142,8 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
_, err = tx.InsertOrganizationMember(ctx, database.InsertOrganizationMemberParams{ _, err = tx.InsertOrganizationMember(ctx, database.InsertOrganizationMemberParams{
OrganizationID: req.OrganizationID, OrganizationID: req.OrganizationID,
UserID: user.ID, UserID: user.ID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
// By default give them membership to the organization. // By default give them membership to the organization.
Roles: orgRoles, Roles: orgRoles,
}) })

View File

@ -23,6 +23,7 @@ import (
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/util/slice" "github.com/coder/coder/v2/coderd/util/slice"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -565,7 +566,7 @@ func TestPostUsers(t *testing.T) {
// should be Never since they haven't performed a request. // should be Never since they haven't performed a request.
for _, user := range allUsersRes.Users { for _, user := range allUsersRes.Users {
if user.ID == firstUser.ID { if user.ID == firstUser.ID {
require.WithinDuration(t, firstUser.LastSeenAt, database.Now(), testutil.WaitShort) require.WithinDuration(t, firstUser.LastSeenAt, dbtime.Now(), testutil.WaitShort)
} else { } else {
require.Zero(t, user.LastSeenAt) require.Zero(t, user.LastSeenAt)
} }

View File

@ -33,6 +33,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/gitauth" "github.com/coder/coder/v2/coderd/gitauth"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
@ -1082,12 +1083,12 @@ func (api *API) workspaceAgentCoordinate(rw http.ResponseWriter, r *http.Request
firstConnectedAt := workspaceAgent.FirstConnectedAt firstConnectedAt := workspaceAgent.FirstConnectedAt
if !firstConnectedAt.Valid { if !firstConnectedAt.Valid {
firstConnectedAt = sql.NullTime{ firstConnectedAt = sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
} }
} }
lastConnectedAt := sql.NullTime{ lastConnectedAt := sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
} }
disconnectedAt := workspaceAgent.DisconnectedAt disconnectedAt := workspaceAgent.DisconnectedAt
@ -1098,7 +1099,7 @@ func (api *API) workspaceAgentCoordinate(rw http.ResponseWriter, r *http.Request
FirstConnectedAt: firstConnectedAt, FirstConnectedAt: firstConnectedAt,
LastConnectedAt: lastConnectedAt, LastConnectedAt: lastConnectedAt,
DisconnectedAt: disconnectedAt, DisconnectedAt: disconnectedAt,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
LastConnectedReplicaID: uuid.NullUUID{ LastConnectedReplicaID: uuid.NullUUID{
UUID: api.ID, UUID: api.ID,
Valid: true, Valid: true,
@ -1126,7 +1127,7 @@ func (api *API) workspaceAgentCoordinate(rw http.ResponseWriter, r *http.Request
// Only update timestamp if the disconnect is new. // Only update timestamp if the disconnect is new.
if !disconnectedAt.Valid { if !disconnectedAt.Valid {
disconnectedAt = sql.NullTime{ disconnectedAt = sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
} }
} }
@ -1191,7 +1192,7 @@ func (api *API) workspaceAgentCoordinate(rw http.ResponseWriter, r *http.Request
if !disconnectedAt.Valid { if !disconnectedAt.Valid {
connectionStatusChanged = true connectionStatusChanged = true
disconnectedAt = sql.NullTime{ disconnectedAt = sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
} }
} }
@ -1200,7 +1201,7 @@ func (api *API) workspaceAgentCoordinate(rw http.ResponseWriter, r *http.Request
// TODO(mafredri): Should we update it here or allow lastConnectedAt to shadow it? // TODO(mafredri): Should we update it here or allow lastConnectedAt to shadow it?
disconnectedAt = sql.NullTime{} disconnectedAt = sql.NullTime{}
lastConnectedAt = sql.NullTime{ lastConnectedAt = sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
} }
} }
@ -1480,7 +1481,7 @@ func (api *API) workspaceAgentReportStats(rw http.ResponseWriter, r *http.Reques
activityBumpWorkspace(ctx, api.Logger.Named("activity_bump"), api.Database, workspace.ID) activityBumpWorkspace(ctx, api.Logger.Named("activity_bump"), api.Database, workspace.ID)
} }
now := database.Now() now := dbtime.Now()
var errGroup errgroup.Group var errGroup errgroup.Group
errGroup.Go(func() error { errGroup.Go(func() error {
@ -1820,7 +1821,7 @@ func (api *API) workspaceAgentReportLifecycle(rw http.ResponseWriter, r *http.Re
if req.ChangedAt.IsZero() { if req.ChangedAt.IsZero() {
// Backwards compatibility with older agents. // Backwards compatibility with older agents.
req.ChangedAt = database.Now() req.ChangedAt = dbtime.Now()
} }
changedAt := sql.NullTime{Time: req.ChangedAt, Valid: true} changedAt := sql.NullTime{Time: req.ChangedAt, Valid: true}
@ -2083,7 +2084,7 @@ func (api *API) workspaceAgentsGitAuth(rw http.ResponseWriter, r *http.Request)
// to expire. // to expire.
// See // See
// https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app. // https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app.
if gitAuthLink.OAuthExpiry.Before(database.Now()) && !gitAuthLink.OAuthExpiry.IsZero() { if gitAuthLink.OAuthExpiry.Before(dbtime.Now()) && !gitAuthLink.OAuthExpiry.IsZero() {
continue continue
} }
valid, _, err := gitAuthConfig.ValidateToken(ctx, gitAuthLink.OAuthAccessToken) valid, _, err := gitAuthConfig.ValidateToken(ctx, gitAuthLink.OAuthAccessToken)

View File

@ -23,6 +23,7 @@ import (
"github.com/coder/coder/v2/agent" "github.com/coder/coder/v2/agent"
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/codersdk/agentsdk"
"github.com/coder/coder/v2/provisioner/echo" "github.com/coder/coder/v2/provisioner/echo"
@ -307,11 +308,11 @@ func TestWorkspaceAgentStartupLogs(t *testing.T) {
err := agentClient.PatchLogs(ctx, agentsdk.PatchLogs{ err := agentClient.PatchLogs(ctx, agentsdk.PatchLogs{
Logs: []agentsdk.Log{ Logs: []agentsdk.Log{
{ {
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Output: "testing", Output: "testing",
}, },
{ {
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Output: "testing2", Output: "testing2",
}, },
}, },
@ -371,7 +372,7 @@ func TestWorkspaceAgentStartupLogs(t *testing.T) {
err := agentClient.PatchLogs(ctx, agentsdk.PatchLogs{ err := agentClient.PatchLogs(ctx, agentsdk.PatchLogs{
Logs: []agentsdk.Log{ Logs: []agentsdk.Log{
{ {
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Output: "testing", Output: "testing",
}, },
}, },
@ -405,7 +406,7 @@ func TestWorkspaceAgentStartupLogs(t *testing.T) {
err = agentClient.PatchLogs(ctx, agentsdk.PatchLogs{ err = agentClient.PatchLogs(ctx, agentsdk.PatchLogs{
Logs: []agentsdk.Log{ Logs: []agentsdk.Log{
{ {
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Output: "testing2", Output: "testing2",
}, },
}, },
@ -458,7 +459,7 @@ func TestWorkspaceAgentStartupLogs(t *testing.T) {
agentClient.SetSessionToken(authToken) agentClient.SetSessionToken(authToken)
err = agentClient.PatchLogs(ctx, agentsdk.PatchLogs{ err = agentClient.PatchLogs(ctx, agentsdk.PatchLogs{
Logs: []agentsdk.Log{{ Logs: []agentsdk.Log{{
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Output: strings.Repeat("a", (1<<20)+1), Output: strings.Repeat("a", (1<<20)+1),
}}, }},
}) })

View File

@ -14,6 +14,7 @@ import (
"github.com/coder/coder/v2/coderd/apikey" "github.com/coder/coder/v2/coderd/apikey"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -107,7 +108,7 @@ func (api *API) workspaceApplicationAuth(rw http.ResponseWriter, r *http.Request
exp := apiKey.ExpiresAt exp := apiKey.ExpiresAt
lifetimeSeconds := apiKey.LifetimeSeconds lifetimeSeconds := apiKey.LifetimeSeconds
if exp.IsZero() || time.Until(exp) > api.DeploymentValues.SessionDuration.Value() { if exp.IsZero() || time.Until(exp) > api.DeploymentValues.SessionDuration.Value() {
exp = database.Now().Add(api.DeploymentValues.SessionDuration.Value()) exp = dbtime.Now().Add(api.DeploymentValues.SessionDuration.Value())
lifetimeSeconds = int64(api.DeploymentValues.SessionDuration.Value().Seconds()) lifetimeSeconds = int64(api.DeploymentValues.SessionDuration.Value().Seconds())
} }
cookie, _, err := api.createAPIKey(ctx, apikey.CreateParams{ cookie, _, err := api.createAPIKey(ctx, apikey.CreateParams{

View File

@ -19,7 +19,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/agent/agentssh" "github.com/coder/coder/v2/agent/agentssh"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/tracing" "github.com/coder/coder/v2/coderd/tracing"
@ -600,7 +600,7 @@ func (s *Server) proxyWorkspaceApp(rw http.ResponseWriter, r *http.Request, appT
s.collectStats(report) s.collectStats(report)
defer func() { defer func() {
// We must use defer here because ServeHTTP may panic. // We must use defer here because ServeHTTP may panic.
report.SessionEndedAt = database.Now() report.SessionEndedAt = dbtime.Now()
s.collectStats(report) s.collectStats(report)
}() }()
@ -700,7 +700,7 @@ func (s *Server) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) {
report := newStatsReportFromSignedToken(*appToken) report := newStatsReportFromSignedToken(*appToken)
s.collectStats(report) s.collectStats(report)
defer func() { defer func() {
report.SessionEndedAt = database.Now() report.SessionEndedAt = dbtime.Now()
s.collectStats(report) s.collectStats(report)
}() }()

View File

@ -12,6 +12,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
) )
const ( const (
@ -43,7 +44,7 @@ func newStatsReportFromSignedToken(token SignedToken) StatsReport {
AccessMethod: token.AccessMethod, AccessMethod: token.AccessMethod,
SlugOrPort: token.AppSlugOrPort, SlugOrPort: token.AppSlugOrPort,
SessionID: uuid.New(), SessionID: uuid.New(),
SessionStartedAt: database.Now(), SessionStartedAt: dbtime.Now(),
Requests: 1, Requests: 1,
} }
} }
@ -294,7 +295,7 @@ func (sc *StatsCollector) rollup(now time.Time) []StatsReport {
// Report an end time for incomplete sessions, it will // Report an end time for incomplete sessions, it will
// be updated later. This ensures that data in the DB // be updated later. This ensures that data in the DB
// will have an end time even if the service is stopped. // will have an end time even if the service is stopped.
r.SessionEndedAt = now.UTC() // Use UTC like database.Now(). r.SessionEndedAt = now.UTC() // Use UTC like dbtime.Now().
} }
report = append(report, r) // Report it (ended or incomplete). report = append(report, r) // Report it (ended or incomplete).
if stat.SessionEndedAt.IsZero() { if stat.SessionEndedAt.IsZero() {

View File

@ -13,7 +13,7 @@ import (
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/workspaceapps" "github.com/coder/coder/v2/coderd/workspaceapps"
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
) )
@ -63,7 +63,7 @@ func TestStatsCollector(t *testing.T) {
someUUID := uuid.New() someUUID := uuid.New()
rollupWindow := time.Minute rollupWindow := time.Minute
start := database.Now().Truncate(time.Minute).UTC() start := dbtime.Now().Truncate(time.Minute).UTC()
end := start.Add(10 * time.Second) end := start.Add(10 * time.Second)
tests := []struct { tests := []struct {
@ -351,7 +351,7 @@ func TestStatsCollector_backlog(t *testing.T) {
rollupWindow := time.Minute rollupWindow := time.Minute
flush := make(chan chan<- struct{}, 1) flush := make(chan chan<- struct{}, 1)
start := database.Now().Truncate(time.Minute).UTC() start := dbtime.Now().Truncate(time.Minute).UTC()
var now atomic.Pointer[time.Time] var now atomic.Pointer[time.Time]
now.Store(&start) now.Store(&start)
@ -414,8 +414,8 @@ func TestStatsCollector_Close(t *testing.T) {
collector.Collect(workspaceapps.StatsReport{ collector.Collect(workspaceapps.StatsReport{
SessionID: uuid.New(), SessionID: uuid.New(),
SessionStartedAt: database.Now(), SessionStartedAt: dbtime.Now(),
SessionEndedAt: database.Now(), SessionEndedAt: dbtime.Now(),
Requests: 1, Requests: 1,
}) })

View File

@ -12,7 +12,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
@ -168,7 +168,7 @@ func (k SecurityKey) EncryptAPIKey(payload EncryptedAPIKeyPayload) (string, erro
if payload.ExpiresAt.IsZero() { if payload.ExpiresAt.IsZero() {
// Very short expiry as these keys are only used once as part of an // Very short expiry as these keys are only used once as part of an
// automatic redirection flow. // automatic redirection flow.
payload.ExpiresAt = database.Now().Add(time.Minute) payload.ExpiresAt = dbtime.Now().Add(time.Minute)
} }
payloadBytes, err := json.Marshal(payload) payloadBytes, err := json.Marshal(payload)
@ -227,7 +227,7 @@ func (k SecurityKey) DecryptAPIKey(encryptedAPIKey string) (string, error) {
} }
// Validate expiry. // Validate expiry.
if payload.ExpiresAt.Before(database.Now()) { if payload.ExpiresAt.Before(dbtime.Now()) {
return "", xerrors.New("encrypted API key expired") return "", xerrors.New("encrypted API key expired")
} }

View File

@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/workspaceapps" "github.com/coder/coder/v2/coderd/workspaceapps"
"github.com/coder/coder/v2/cryptorand" "github.com/coder/coder/v2/cryptorand"
) )
@ -467,7 +467,7 @@ func TestAPIKeyEncryption(t *testing.T) {
key := genAPIKey(t) key := genAPIKey(t)
encrypted, err := coderdtest.AppSecurityKey.EncryptAPIKey(workspaceapps.EncryptedAPIKeyPayload{ encrypted, err := coderdtest.AppSecurityKey.EncryptAPIKey(workspaceapps.EncryptedAPIKeyPayload{
APIKey: key, APIKey: key,
ExpiresAt: database.Now().Add(-1 * time.Hour), ExpiresAt: dbtime.Now().Add(-1 * time.Hour),
}) })
require.NoError(t, err) require.NoError(t, err)

View File

@ -19,6 +19,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -151,7 +152,7 @@ func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) {
AfterID: paginationParams.AfterID, AfterID: paginationParams.AfterID,
OffsetOpt: int32(paginationParams.Offset), OffsetOpt: int32(paginationParams.Offset),
LimitOpt: int32(paginationParams.Limit), LimitOpt: int32(paginationParams.Limit),
Since: database.Time(since), Since: dbtime.Time(since),
} }
workspaceBuilds, err = store.GetWorkspaceBuildsByWorkspaceID(ctx, req) workspaceBuilds, err = store.GetWorkspaceBuildsByWorkspaceID(ctx, req)
if xerrors.Is(err, sql.ErrNoRows) { if xerrors.Is(err, sql.ErrNoRows) {
@ -469,11 +470,11 @@ func (api *API) patchCancelWorkspaceBuild(rw http.ResponseWriter, r *http.Reques
err = api.Database.UpdateProvisionerJobWithCancelByID(ctx, database.UpdateProvisionerJobWithCancelByIDParams{ err = api.Database.UpdateProvisionerJobWithCancelByID(ctx, database.UpdateProvisionerJobWithCancelByIDParams{
ID: job.ID, ID: job.ID,
CanceledAt: sql.NullTime{ CanceledAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
CompletedAt: sql.NullTime{ CompletedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
// If the job is running, don't mark it completed! // If the job is running, don't mark it completed!
Valid: !job.WorkerID.Valid, Valid: !job.WorkerID.Valid,
}, },

View File

@ -19,6 +19,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/provisioner/echo" "github.com/coder/coder/v2/provisioner/echo"
@ -171,7 +172,7 @@ func TestWorkspaceBuilds(t *testing.T) {
// Test since // Test since
builds, err = client.WorkspaceBuilds(ctx, builds, err = client.WorkspaceBuilds(ctx,
codersdk.WorkspaceBuildsRequest{WorkspaceID: workspace.ID, Since: database.Now().Add(time.Minute)}, codersdk.WorkspaceBuildsRequest{WorkspaceID: workspace.ID, Since: dbtime.Now().Add(time.Minute)},
) )
require.NoError(t, err) require.NoError(t, err)
require.Len(t, builds, 0) require.Len(t, builds, 0)
@ -179,7 +180,7 @@ func TestWorkspaceBuilds(t *testing.T) {
require.NotNil(t, builds) require.NotNil(t, builds)
builds, err = client.WorkspaceBuilds(ctx, builds, err = client.WorkspaceBuilds(ctx,
codersdk.WorkspaceBuildsRequest{WorkspaceID: workspace.ID, Since: database.Now().Add(-time.Hour)}, codersdk.WorkspaceBuildsRequest{WorkspaceID: workspace.ID, Since: dbtime.Now().Add(-time.Hour)},
) )
require.NoError(t, err) require.NoError(t, err)
require.Len(t, builds, 1) require.Len(t, builds, 1)

View File

@ -18,6 +18,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -454,7 +455,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
workspaceBuild *database.WorkspaceBuild workspaceBuild *database.WorkspaceBuild
) )
err = api.Database.InTx(func(db database.Store) error { err = api.Database.InTx(func(db database.Store) error {
now := database.Now() now := dbtime.Now()
// Workspaces are created without any versions. // Workspaces are created without any versions.
workspace, err = db.InsertWorkspace(ctx, database.InsertWorkspaceParams{ workspace, err = db.InsertWorkspace(ctx, database.InsertWorkspaceParams{
ID: uuid.New(), ID: uuid.New(),
@ -468,7 +469,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
Ttl: dbTTL, Ttl: dbTTL,
// The workspaces page will sort by last used at, and it's useful to // The workspaces page will sort by last used at, and it's useful to
// have the newly created workspace at the top of the list! // have the newly created workspace at the top of the list!
LastUsedAt: database.Now(), LastUsedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return xerrors.Errorf("insert workspace: %w", err) return xerrors.Errorf("insert workspace: %w", err)
@ -825,7 +826,7 @@ func (api *API) putWorkspaceDormant(rw http.ResponseWriter, r *http.Request) {
Valid: req.Dormant, Valid: req.Dormant,
} }
if req.Dormant { if req.Dormant {
dormantAt.Time = database.Now() dormantAt.Time = dbtime.Now()
} }
workspace, err := api.Database.UpdateWorkspaceDormantDeletingAt(ctx, database.UpdateWorkspaceDormantDeletingAtParams{ workspace, err := api.Database.UpdateWorkspaceDormantDeletingAt(ctx, database.UpdateWorkspaceDormantDeletingAtParams{

View File

@ -26,6 +26,7 @@ import (
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/parameter" "github.com/coder/coder/v2/coderd/parameter"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/schedule" "github.com/coder/coder/v2/coderd/schedule"
@ -1525,7 +1526,7 @@ func TestWorkspaceFilterManual(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
now := database.Now() now := dbtime.Now()
before := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) before := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
_ = coderdtest.AwaitWorkspaceBuildJob(t, client, before.LatestBuild.ID) _ = coderdtest.AwaitWorkspaceBuildJob(t, client, before.LatestBuild.ID)

View File

@ -16,6 +16,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/provisionerdserver" "github.com/coder/coder/v2/coderd/provisionerdserver"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -300,7 +301,7 @@ func (b *Builder) buildTx(authFunc func(action rbac.Action, object rbac.Objecter
} }
tags := provisionerdserver.MutateTags(b.workspace.OwnerID, templateVersionJob.Tags) tags := provisionerdserver.MutateTags(b.workspace.OwnerID, templateVersionJob.Tags)
now := database.Now() now := dbtime.Now()
provisionerJob, err := b.store.InsertProvisionerJob(b.ctx, database.InsertProvisionerJobParams{ provisionerJob, err := b.store.InsertProvisionerJob(b.ctx, database.InsertProvisionerJobParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: now, CreatedAt: now,

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbmock" "github.com/coder/coder/v2/coderd/database/dbmock"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/provisionerdserver" "github.com/coder/coder/v2/coderd/provisionerdserver"
"github.com/coder/coder/v2/coderd/wsbuilder" "github.com/coder/coder/v2/coderd/wsbuilder"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -649,9 +650,9 @@ func withActiveVersion(params []database.TemplateVersionParameter) func(mTx *dbm
provisionerdserver.TagScope: provisionerdserver.ScopeUser, provisionerdserver.TagScope: provisionerdserver.ScopeUser,
}, },
FileID: activeFileID, FileID: activeFileID,
StartedAt: sql.NullTime{Time: database.Now(), Valid: true}, StartedAt: sql.NullTime{Time: dbtime.Now(), Valid: true},
UpdatedAt: time.Now(), UpdatedAt: time.Now(),
CompletedAt: sql.NullTime{Time: database.Now(), Valid: true}, CompletedAt: sql.NullTime{Time: dbtime.Now(), Valid: true},
}, nil) }, nil)
paramsCall := mTx.EXPECT().GetTemplateVersionParameters(gomock.Any(), activeVersionID). paramsCall := mTx.EXPECT().GetTemplateVersionParameters(gomock.Any(), activeVersionID).
Times(1) Times(1)
@ -689,9 +690,9 @@ func withInactiveVersion(params []database.TemplateVersionParameter) func(mTx *d
provisionerdserver.TagScope: provisionerdserver.ScopeUser, provisionerdserver.TagScope: provisionerdserver.ScopeUser,
}, },
FileID: inactiveFileID, FileID: inactiveFileID,
StartedAt: sql.NullTime{Time: database.Now(), Valid: true}, StartedAt: sql.NullTime{Time: dbtime.Now(), Valid: true},
UpdatedAt: time.Now(), UpdatedAt: time.Now(),
CompletedAt: sql.NullTime{Time: database.Now(), Valid: true}, CompletedAt: sql.NullTime{Time: dbtime.Now(), Valid: true},
}, nil) }, nil)
paramsCall := mTx.EXPECT().GetTemplateVersionParameters(gomock.Any(), inactiveVersionID). paramsCall := mTx.EXPECT().GetTemplateVersionParameters(gomock.Any(), inactiveVersionID).
Times(1) Times(1)
@ -728,9 +729,9 @@ func withLastBuildFound(mTx *dbmock.MockStore) {
StorageMethod: database.ProvisionerStorageMethodFile, StorageMethod: database.ProvisionerStorageMethodFile,
FileID: inactiveFileID, FileID: inactiveFileID,
Type: database.ProvisionerJobTypeWorkspaceBuild, Type: database.ProvisionerJobTypeWorkspaceBuild,
StartedAt: sql.NullTime{Time: database.Now(), Valid: true}, StartedAt: sql.NullTime{Time: dbtime.Now(), Valid: true},
UpdatedAt: time.Now(), UpdatedAt: time.Now(),
CompletedAt: sql.NullTime{Time: database.Now(), Valid: true}, CompletedAt: sql.NullTime{Time: dbtime.Now(), Valid: true},
}, nil) }, nil)
} }

View File

@ -41,7 +41,7 @@ func (w *startupLogsWriter) Write(p []byte) (int, error) {
w.buf.Reset() w.buf.Reset()
} }
err := w.send(w.ctx, Log{ err := w.send(w.ctx, Log{
CreatedAt: time.Now().UTC(), // UTC, like database.Now(). CreatedAt: time.Now().UTC(), // UTC, like dbtime.Now().
Level: w.level, Level: w.level,
Output: string(partial) + string(p[:nl-cr]), Output: string(partial) + string(p[:nl-cr]),
Source: w.source, Source: w.source,
@ -64,7 +64,7 @@ func (w *startupLogsWriter) Close() error {
if w.buf.Len() > 0 { if w.buf.Len() > 0 {
defer w.buf.Reset() defer w.buf.Reset()
return w.send(w.ctx, Log{ return w.send(w.ctx, Log{
CreatedAt: time.Now().UTC(), // UTC, like database.Now(). CreatedAt: time.Now().UTC(), // UTC, like dbtime.Now().
Level: w.level, Level: w.level,
Output: w.buf.String(), Output: w.buf.String(),
Source: w.source, Source: w.source,

View File

@ -16,6 +16,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/enterprise/audit" "github.com/coder/coder/v2/enterprise/audit"
@ -112,8 +113,8 @@ func TestEntitlements(t *testing.T) {
//nolint:gocritic // unit test //nolint:gocritic // unit test
ctx := testDBAuthzRole(context.Background()) ctx := testDBAuthzRole(context.Background())
_, err = api.Database.InsertLicense(ctx, database.InsertLicenseParams{ _, err = api.Database.InsertLicense(ctx, database.InsertLicenseParams{
UploadedAt: database.Now(), UploadedAt: dbtime.Now(),
Exp: database.Now().AddDate(1, 0, 0), Exp: dbtime.Now().AddDate(1, 0, 0),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{ JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: license.Features{ Features: license.Features{
codersdk.FeatureAuditLog: 1, codersdk.FeatureAuditLog: 1,
@ -142,8 +143,8 @@ func TestEntitlements(t *testing.T) {
ctx := context.Background() ctx := context.Background()
//nolint:gocritic // unit test //nolint:gocritic // unit test
_, err = api.Database.InsertLicense(testDBAuthzRole(ctx), database.InsertLicenseParams{ _, err = api.Database.InsertLicense(testDBAuthzRole(ctx), database.InsertLicenseParams{
UploadedAt: database.Now(), UploadedAt: dbtime.Now(),
Exp: database.Now().AddDate(1, 0, 0), Exp: dbtime.Now().AddDate(1, 0, 0),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{ JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: license.Features{ Features: license.Features{
codersdk.FeatureAuditLog: 1, codersdk.FeatureAuditLog: 1,
@ -154,18 +155,18 @@ func TestEntitlements(t *testing.T) {
// Expired // Expired
//nolint:gocritic // unit test //nolint:gocritic // unit test
_, err = api.Database.InsertLicense(testDBAuthzRole(ctx), database.InsertLicenseParams{ _, err = api.Database.InsertLicense(testDBAuthzRole(ctx), database.InsertLicenseParams{
UploadedAt: database.Now(), UploadedAt: dbtime.Now(),
Exp: database.Now().AddDate(-1, 0, 0), Exp: dbtime.Now().AddDate(-1, 0, 0),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{ JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
ExpiresAt: database.Now().AddDate(-1, 0, 0), ExpiresAt: dbtime.Now().AddDate(-1, 0, 0),
}), }),
}) })
require.NoError(t, err) require.NoError(t, err)
// Invalid // Invalid
//nolint:gocritic // unit test //nolint:gocritic // unit test
_, err = api.Database.InsertLicense(testDBAuthzRole(ctx), database.InsertLicenseParams{ _, err = api.Database.InsertLicense(testDBAuthzRole(ctx), database.InsertLicenseParams{
UploadedAt: database.Now(), UploadedAt: dbtime.Now(),
Exp: database.Now().AddDate(1, 0, 0), Exp: dbtime.Now().AddDate(1, 0, 0),
JWT: "invalid", JWT: "invalid",
}) })
require.NoError(t, err) require.NoError(t, err)

View File

@ -10,6 +10,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
) )
const ( const (
@ -44,12 +45,12 @@ func CheckInactiveUsersWithOptions(ctx context.Context, logger slog.Logger, db d
} }
startTime := time.Now() startTime := time.Now()
lastSeenAfter := database.Now().Add(-dormancyPeriod) lastSeenAfter := dbtime.Now().Add(-dormancyPeriod)
logger.Debug(ctx, "check inactive user accounts", slog.F("dormancy_period", dormancyPeriod), slog.F("last_seen_after", lastSeenAfter)) logger.Debug(ctx, "check inactive user accounts", slog.F("dormancy_period", dormancyPeriod), slog.F("last_seen_after", lastSeenAfter))
updatedUsers, err := db.UpdateInactiveUsersToDormant(ctx, database.UpdateInactiveUsersToDormantParams{ updatedUsers, err := db.UpdateInactiveUsersToDormant(ctx, database.UpdateInactiveUsersToDormantParams{
LastSeenAfter: lastSeenAfter, LastSeenAfter: lastSeenAfter,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil && !xerrors.Is(err, sql.ErrNoRows) { if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
logger.Error(ctx, "can't mark inactive users as dormant", slog.Error(err)) logger.Error(ctx, "can't mark inactive users as dormant", slog.Error(err))

View File

@ -12,6 +12,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/enterprise/coderd/license"
@ -269,7 +270,7 @@ func TestEntitlements(t *testing.T) {
_, err = db.UpdateUserStatus(context.Background(), database.UpdateUserStatusParams{ _, err = db.UpdateUserStatus(context.Background(), database.UpdateUserStatusParams{
ID: activeUser1.ID, ID: activeUser1.ID,
Status: database.UserStatusActive, Status: database.UserStatusActive,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err) require.NoError(t, err)
activeUser2, err := db.InsertUser(context.Background(), database.InsertUserParams{ activeUser2, err := db.InsertUser(context.Background(), database.InsertUserParams{
@ -281,7 +282,7 @@ func TestEntitlements(t *testing.T) {
_, err = db.UpdateUserStatus(context.Background(), database.UpdateUserStatusParams{ _, err = db.UpdateUserStatus(context.Background(), database.UpdateUserStatusParams{
ID: activeUser2.ID, ID: activeUser2.ID,
Status: database.UserStatusActive, Status: database.UserStatusActive,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
require.NoError(t, err) require.NoError(t, err)
_, err = db.InsertUser(context.Background(), database.InsertUserParams{ _, err = db.InsertUser(context.Background(), database.InsertUserParams{

View File

@ -23,6 +23,7 @@ import (
"github.com/coder/coder/v2/coderd" "github.com/coder/coder/v2/coderd"
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -120,7 +121,7 @@ func (api *API) postLicense(rw http.ResponseWriter, r *http.Request) {
id = uuid.New() id = uuid.New()
} }
dl, err := api.Database.InsertLicense(ctx, database.InsertLicenseParams{ dl, err := api.Database.InsertLicense(ctx, database.InsertLicenseParams{
UploadedAt: database.Now(), UploadedAt: dbtime.Now(),
JWT: addLicense.License, JWT: addLicense.License,
Exp: expTime, Exp: expTime,
UUID: id, UUID: id,

View File

@ -25,6 +25,7 @@ import (
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd" "github.com/coder/coder/v2/coderd"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/provisionerdserver" "github.com/coder/coder/v2/coderd/provisionerdserver"
@ -199,7 +200,7 @@ func (api *API) provisionerDaemonServe(rw http.ResponseWriter, r *http.Request)
) )
daemon, err := api.Database.InsertProvisionerDaemon(ctx, database.InsertProvisionerDaemonParams{ daemon, err := api.Database.InsertProvisionerDaemon(ctx, database.InsertProvisionerDaemonParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
Name: name, Name: name,
Provisioners: provisioners, Provisioners: provisioners,
Tags: tags, Tags: tags,

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
agpl "github.com/coder/coder/v2/coderd/schedule" agpl "github.com/coder/coder/v2/coderd/schedule"
"github.com/coder/coder/v2/coderd/tracing" "github.com/coder/coder/v2/coderd/tracing"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
@ -31,7 +32,7 @@ type EnterpriseTemplateScheduleStore struct {
// update. // update.
UserQuietHoursScheduleStore *atomic.Pointer[agpl.UserQuietHoursScheduleStore] UserQuietHoursScheduleStore *atomic.Pointer[agpl.UserQuietHoursScheduleStore]
// Custom time.Now() function to use in tests. Defaults to database.Now(). // Custom time.Now() function to use in tests. Defaults to dbtime.Now().
TimeNowFn func() time.Time TimeNowFn func() time.Time
} }
@ -47,7 +48,7 @@ func (s *EnterpriseTemplateScheduleStore) now() time.Time {
if s.TimeNowFn != nil { if s.TimeNowFn != nil {
return s.TimeNowFn() return s.TimeNowFn()
} }
return database.Now() return dbtime.Now()
} }
// Get implements agpl.TemplateScheduleStore. // Get implements agpl.TemplateScheduleStore.
@ -146,7 +147,7 @@ func (s *EnterpriseTemplateScheduleStore) Set(ctx context.Context, db database.S
var dormantAt time.Time var dormantAt time.Time
if opts.UpdateWorkspaceDormantAt { if opts.UpdateWorkspaceDormantAt {
dormantAt = database.Now() dormantAt = dbtime.Now()
} }
// If we updated the time_til_dormant_autodelete we need to update all the workspaces deleting_at // If we updated the time_til_dormant_autodelete we need to update all the workspaces deleting_at
@ -165,7 +166,7 @@ func (s *EnterpriseTemplateScheduleStore) Set(ctx context.Context, db database.S
if opts.UpdateWorkspaceLastUsedAt { if opts.UpdateWorkspaceLastUsedAt {
err = tx.UpdateTemplateWorkspacesLastUsedAt(ctx, database.UpdateTemplateWorkspacesLastUsedAtParams{ err = tx.UpdateTemplateWorkspacesLastUsedAt(ctx, database.UpdateTemplateWorkspacesLastUsedAtParams{
TemplateID: tpl.ID, TemplateID: tpl.ID,
LastUsedAt: database.Now(), LastUsedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
return xerrors.Errorf("update template workspaces last_used_at: %w", err) return xerrors.Errorf("update template workspaces last_used_at: %w", err)

View File

@ -17,6 +17,7 @@ import (
agpl "github.com/coder/coder/v2/coderd" agpl "github.com/coder/coder/v2/coderd"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
@ -173,7 +174,7 @@ func (api *API) scimPostUser(rw http.ResponseWriter, r *http.Request) {
ID: dbUser.ID, ID: dbUser.ID,
// The user will get transitioned to Active after logging in. // The user will get transitioned to Active after logging in.
Status: database.UserStatusDormant, Status: database.UserStatusDormant,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
_ = handlerutil.WriteError(rw, err) _ = handlerutil.WriteError(rw, err)
@ -287,7 +288,7 @@ func (api *API) scimPatchUser(rw http.ResponseWriter, r *http.Request) {
_, err = api.Database.UpdateUserStatus(dbauthz.AsSystemRestricted(r.Context()), database.UpdateUserStatusParams{ _, err = api.Database.UpdateUserStatus(dbauthz.AsSystemRestricted(r.Context()), database.UpdateUserStatusParams{
ID: dbUser.ID, ID: dbUser.ID,
Status: status, Status: status,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if err != nil { if err != nil {
_ = handlerutil.WriteError(rw, err) _ = handlerutil.WriteError(rw, err)

View File

@ -20,6 +20,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac"
@ -356,8 +357,8 @@ func (api *API) postWorkspaceProxy(rw http.ResponseWriter, r *http.Request) {
DerpEnabled: true, DerpEnabled: true,
// Disabled by default, but blah blah blah. // Disabled by default, but blah blah blah.
DerpOnly: false, DerpOnly: false,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
}) })
if database.IsUniqueViolation(err, database.UniqueWorkspaceProxiesLowerNameIndex) { if database.IsUniqueViolation(err, database.UniqueWorkspaceProxiesLowerNameIndex) {
httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{ httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{

View File

@ -20,6 +20,7 @@ import (
"github.com/coder/coder/v2/buildinfo" "github.com/coder/coder/v2/buildinfo"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub" "github.com/coder/coder/v2/coderd/database/pubsub"
) )
@ -66,9 +67,9 @@ func New(ctx context.Context, logger slog.Logger, db database.Store, ps pubsub.P
// nolint:gocritic // Inserting a replica is a system function. // nolint:gocritic // Inserting a replica is a system function.
replica, err := db.InsertReplica(dbauthz.AsSystemRestricted(ctx), database.InsertReplicaParams{ replica, err := db.InsertReplica(dbauthz.AsSystemRestricted(ctx), database.InsertReplicaParams{
ID: options.ID, ID: options.ID,
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
StartedAt: database.Now(), StartedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Hostname: hostname, Hostname: hostname,
RegionID: options.RegionID, RegionID: options.RegionID,
RelayAddress: options.RelayAddress, RelayAddress: options.RelayAddress,
@ -144,7 +145,7 @@ func (m *Manager) PublishUpdate() error {
// If the replica was updated > the time, it's considered healthy. // If the replica was updated > the time, it's considered healthy.
// If the replica was updated < the time, it's considered stale. // If the replica was updated < the time, it's considered stale.
func (m *Manager) updateInterval() time.Time { func (m *Manager) updateInterval() time.Time {
return database.Now().Add(-3 * m.options.UpdateInterval) return dbtime.Now().Add(-3 * m.options.UpdateInterval)
} }
// loop runs the replica update sequence on an update interval. // loop runs the replica update sequence on an update interval.
@ -305,7 +306,7 @@ func (m *Manager) syncReplicas(ctx context.Context) error {
// nolint:gocritic // Updating a replica is a system function. // nolint:gocritic // Updating a replica is a system function.
replica, err := m.db.UpdateReplica(dbauthz.AsSystemRestricted(ctx), database.UpdateReplicaParams{ replica, err := m.db.UpdateReplica(dbauthz.AsSystemRestricted(ctx), database.UpdateReplicaParams{
ID: m.self.ID, ID: m.self.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
StartedAt: m.self.StartedAt, StartedAt: m.self.StartedAt,
StoppedAt: m.self.StoppedAt, StoppedAt: m.self.StoppedAt,
RelayAddress: m.self.RelayAddress, RelayAddress: m.self.RelayAddress,
@ -413,10 +414,10 @@ func (m *Manager) Close() error {
// nolint:gocritic // Updating a replica is a system function. // nolint:gocritic // Updating a replica is a system function.
_, err := m.db.UpdateReplica(dbauthz.AsSystemRestricted(ctx), database.UpdateReplicaParams{ _, err := m.db.UpdateReplica(dbauthz.AsSystemRestricted(ctx), database.UpdateReplicaParams{
ID: m.self.ID, ID: m.self.ID,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
StartedAt: m.self.StartedAt, StartedAt: m.self.StartedAt,
StoppedAt: sql.NullTime{ StoppedAt: sql.NullTime{
Time: database.Now(), Time: dbtime.Now(),
Valid: true, Valid: true,
}, },
RelayAddress: m.self.RelayAddress, RelayAddress: m.self.RelayAddress,

View File

@ -18,6 +18,7 @@ import (
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub" "github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/coder/coder/v2/enterprise/replicasync" "github.com/coder/coder/v2/enterprise/replicasync"
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
@ -61,9 +62,9 @@ func TestReplica(t *testing.T) {
db, pubsub := dbtestutil.NewDB(t) db, pubsub := dbtestutil.NewDB(t)
peer, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{ peer, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
StartedAt: database.Now(), StartedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Hostname: "something", Hostname: "something",
RelayAddress: srv.URL, RelayAddress: srv.URL,
Primary: true, Primary: true,
@ -106,9 +107,9 @@ func TestReplica(t *testing.T) {
db, pubsub := dbtestutil.NewDB(t) db, pubsub := dbtestutil.NewDB(t)
peer, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{ peer, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: database.Now(), CreatedAt: dbtime.Now(),
StartedAt: database.Now(), StartedAt: dbtime.Now(),
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Hostname: "something", Hostname: "something",
RelayAddress: srv.URL, RelayAddress: srv.URL,
Primary: true, Primary: true,
@ -133,9 +134,9 @@ func TestReplica(t *testing.T) {
db, pubsub := dbtestutil.NewDB(t) db, pubsub := dbtestutil.NewDB(t)
peer, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{ peer, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: database.Now().Add(time.Minute), CreatedAt: dbtime.Now().Add(time.Minute),
StartedAt: database.Now().Add(time.Minute), StartedAt: dbtime.Now().Add(time.Minute),
UpdatedAt: database.Now().Add(time.Minute), UpdatedAt: dbtime.Now().Add(time.Minute),
Hostname: "something", Hostname: "something",
// Fake address to dial! // Fake address to dial!
RelayAddress: "http://127.0.0.1:1", RelayAddress: "http://127.0.0.1:1",
@ -173,7 +174,7 @@ func TestReplica(t *testing.T) {
peer, err := db.InsertReplica(ctx, database.InsertReplicaParams{ peer, err := db.InsertReplica(ctx, database.InsertReplicaParams{
ID: uuid.New(), ID: uuid.New(),
RelayAddress: srv.URL, RelayAddress: srv.URL,
UpdatedAt: database.Now(), UpdatedAt: dbtime.Now(),
Primary: true, Primary: true,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -192,7 +193,7 @@ func TestReplica(t *testing.T) {
db, pubsub := dbtestutil.NewDB(t) db, pubsub := dbtestutil.NewDB(t)
_, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{ _, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{
ID: uuid.New(), ID: uuid.New(),
UpdatedAt: database.Now().Add(-time.Hour), UpdatedAt: dbtime.Now().Add(-time.Hour),
Primary: true, Primary: true,
}) })
require.NoError(t, err) require.NoError(t, err)

View File

@ -14,6 +14,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/enterprise/coderd/license"
) )
@ -68,7 +69,7 @@ func New(db database.Store, url string, keys map[string]ed25519.PublicKey) func(
return xerrors.Errorf("parse uuid: %w", err) return xerrors.Errorf("parse uuid: %w", err)
} }
_, err = db.InsertLicense(ctx, database.InsertLicenseParams{ _, err = db.InsertLicense(ctx, database.InsertLicenseParams{
UploadedAt: database.Now(), UploadedAt: dbtime.Now(),
JWT: string(raw), JWT: string(raw),
Exp: expTime, Exp: expTime,
UUID: id, UUID: id,

View File

@ -26,6 +26,7 @@ import (
"github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbfake" "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/site" "github.com/coder/coder/v2/site"
@ -81,15 +82,15 @@ func TestInjectionFailureProducesCleanHTML(t *testing.T) {
user := dbgen.User(t, db, database.User{}) user := dbgen.User(t, db, database.User{})
_, token := dbgen.APIKey(t, db, database.APIKey{ _, token := dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID, UserID: user.ID,
LastUsed: database.Now().Add(-time.Hour), LastUsed: dbtime.Now().Add(-time.Hour),
ExpiresAt: database.Now().Add(-time.Second), ExpiresAt: dbtime.Now().Add(-time.Second),
LoginType: database.LoginTypeGithub, LoginType: database.LoginTypeGithub,
}) })
_ = dbgen.UserLink(t, db, database.UserLink{ _ = dbgen.UserLink(t, db, database.UserLink{
UserID: user.ID, UserID: user.ID,
LoginType: database.LoginTypeGithub, LoginType: database.LoginTypeGithub,
OAuthRefreshToken: "hello", OAuthRefreshToken: "hello",
OAuthExpiry: database.Now().Add(-time.Second), OAuthExpiry: dbtime.Now().Add(-time.Second),
}) })
binFs := http.FS(fstest.MapFS{}) binFs := http.FS(fstest.MapFS{})

View File

@ -43,7 +43,7 @@ import (
"tailscale.com/wgengine/wgcfg/nmcfg" "tailscale.com/wgengine/wgcfg/nmcfg"
"cdr.dev/slog" "cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/cryptorand" "github.com/coder/coder/v2/cryptorand"
) )
@ -880,7 +880,7 @@ func (c *Conn) selfNode() *Node {
node := &Node{ node := &Node{
ID: c.netMap.SelfNode.ID, ID: c.netMap.SelfNode.ID,
AsOf: database.Now(), AsOf: dbtime.Now(),
Key: c.netMap.SelfNode.Key, Key: c.netMap.SelfNode.Key,
Addresses: c.netMap.SelfNode.Addresses, Addresses: c.netMap.SelfNode.Addresses,
AllowedIPs: c.netMap.SelfNode.AllowedIPs, AllowedIPs: c.netMap.SelfNode.AllowedIPs,