Skip to content

Commit 1650803

Browse files
committed
Merge branch 'main' into window-audit/presleyp
2 parents b40a80e + e6ead7d commit 1650803

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+491
-238
lines changed

.github/ISSUE_TEMPLATE/bug-report.yml

Lines changed: 0 additions & 40 deletions
This file was deleted.

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.

.github/ISSUE_TEMPLATE/enhancement.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

.github/ISSUE_TEMPLATE/feedback.yml

Lines changed: 0 additions & 10 deletions
This file was deleted.

.github/workflows/typos.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ MacOS = "macOS"
88
# do as sudo replacement
99
doas = "doas"
1010
darcula = "darcula"
11+
Hashi = "Hashi"
1112

1213
[files]
1314
extend-exclude = [

README.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ Discord"](https://img.shields.io/badge/join-us%20on%20Discord-gray.svg?longCache
77
[![Twitter
88
Follow](https://img.shields.io/twitter/follow/coderhq?label=%40coderhq&style=social)](https://twitter.com/coderhq)
99

10-
Coder creates remote development machines so your team can develop from anywhere.
10+
Software development on your infrastructure. Offload your team's development from local workstations to cloud servers. Onboard developers in minutes. Build, test and compile at the speed of the cloud. Keep your source code and data behind your firewall.
11+
12+
> "By leveraging Terraform, Coder lets developers run any IDE on any compute platform including on-prem, AWS, Azure, GCP, DigitalOcean, Kubernetes, Docker, and more, with workspaces running on Linux, Windows, or Mac." - **Kevin Fishner Chief of Staff at [HashiCorp](https://hashicorp.com/)**
13+
1114

1215
<p align="center">
1316
<img src="./docs/images/hero-image.png">
@@ -27,10 +30,15 @@ Coder creates remote development machines so your team can develop from anywhere
2730
- Access your environment from any place on any client (even an iPad)
2831
- Onboard instantly then stay up to date continuously
2932

30-
## Getting Started
33+
## Recommended Reading
3134

32-
> **Note**:
33-
> Coder is in a beta state. [Report issues here](https://github.com/coder/coder/issues/new).
35+
- [How our development team shares one giant bare metal machine](https://coder.com/blog/how-our-development-team-shares-one-giant-bare-metal-machine?utm_source=github.com/coder/coder&utm_medium=github&utm_campaign=readme.md)
36+
- [Laptop development is dead: why remote development is the future](https://medium.com/@elliotgraebert/laptop-development-is-dead-why-remote-development-is-the-future-f92ce103fd13)
37+
- [Learn how Palantir improved build times by 78% with coder](https://blog.palantir.com/the-benefits-of-remote-ephemeral-workspaces-1a1251ed6e53).
38+
- [A software development environment is not just a container](https://coder.com/blog/not-a-container?utm_source=github.com/coder/coder&utm_medium=github&utm_campaign=readme.md).
39+
- [What Coder is not](https://coder.com/docs/coder-oss/latest/index#what-coder-is-not?utm_source=github.com/coder/coder&utm_medium=github&utm_campaign=readme.md).
40+
41+
## Getting Started
3442

3543
The easiest way to install Coder is to use our
3644
[install script](https://github.com/coder/coder/blob/main/install.sh) for Linux
@@ -84,7 +92,7 @@ Please file [an issue](https://github.com/coder/coder/issues/new) if any informa
8492
| [Coder](https://github.com/coder/coder) | Platform | OSS + Self-Managed | Pay your cloud | All [Terraform](https://www.terraform.io/registry/providers) resources, all clouds, multi-architecture: Linux, Mac, Windows, containers, VMs, amd64, arm64 |
8593
| [code-server](https://github.com/cdr/code-server) | Web IDE | OSS + Self-Managed | Pay your cloud | Linux, Mac, Windows, containers, VMs, amd64, arm64 |
8694
| [Coder (Classic)](https://coder.com/docs) | Platform | Self-Managed | Pay your cloud + license fees | Kubernetes Linux Containers |
87-
| [GitHub Codespaces](https://github.com/features/codespaces) | Platform | SaaS | 2x Azure Compute | Linux containers |
95+
| [GitHub Codespaces](https://github.com/features/codespaces) | Platform | SaaS | 2x Azure Compute | Linux Virtual Machines |
8896

8997
---
9098

cli/cliui/agent_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/coder/coder/cli/cliui"
1313
"github.com/coder/coder/codersdk"
1414
"github.com/coder/coder/pty/ptytest"
15+
"github.com/coder/coder/testutil"
1516
)
1617

1718
func TestAgent(t *testing.T) {
@@ -49,3 +50,50 @@ func TestAgent(t *testing.T) {
4950
disconnected.Store(true)
5051
<-done
5152
}
53+
54+
func TestAgentTimeoutWithTroubleshootingURL(t *testing.T) {
55+
t.Parallel()
56+
57+
ctx, _ := testutil.Context(t)
58+
59+
wantURL := "https://coder.com/troubleshoot"
60+
61+
var connected, timeout atomic.Bool
62+
cmd := &cobra.Command{
63+
RunE: func(cmd *cobra.Command, args []string) error {
64+
err := cliui.Agent(cmd.Context(), cmd.OutOrStdout(), cliui.AgentOptions{
65+
WorkspaceName: "example",
66+
Fetch: func(ctx context.Context) (codersdk.WorkspaceAgent, error) {
67+
agent := codersdk.WorkspaceAgent{
68+
Status: codersdk.WorkspaceAgentConnecting,
69+
TroubleshootingURL: "https://coder.com/troubleshoot",
70+
}
71+
switch {
72+
case connected.Load():
73+
agent.Status = codersdk.WorkspaceAgentConnected
74+
case timeout.Load():
75+
agent.Status = codersdk.WorkspaceAgentTimeout
76+
}
77+
return agent, nil
78+
},
79+
FetchInterval: time.Millisecond,
80+
WarnInterval: 5 * time.Millisecond,
81+
})
82+
return err
83+
},
84+
}
85+
ptty := ptytest.New(t)
86+
cmd.SetOutput(ptty.Output())
87+
cmd.SetIn(ptty.Input())
88+
done := make(chan struct{})
89+
go func() {
90+
defer close(done)
91+
err := cmd.ExecuteContext(ctx)
92+
assert.NoError(t, err)
93+
}()
94+
ptty.ExpectMatch("Don't panic")
95+
timeout.Store(true)
96+
ptty.ExpectMatch(wantURL)
97+
connected.Store(true)
98+
<-done
99+
}

cli/deployment/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,13 @@ func newConfig() *codersdk.DeploymentConfig {
347347
Hidden: true,
348348
Default: 10 * time.Minute,
349349
},
350+
AgentFallbackTroubleshootingURL: &codersdk.DeploymentConfigField[string]{
351+
Name: "Agent Fallback Troubleshooting URL",
352+
Usage: "URL to use for agent troubleshooting when not set in the template",
353+
Flag: "agent-fallback-troubleshooting-url",
354+
Hidden: true,
355+
Default: "https://coder.com/docs/coder-oss/latest/templates#troubleshooting-templates",
356+
},
350357
AuditLogging: &codersdk.DeploymentConfigField[bool]{
351358
Name: "Audit Logging",
352359
Usage: "Specifies whether audit logging is enabled.",

cli/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ func newProvisionerDaemon(
961961

962962
// nolint: revive
963963
func printLogo(cmd *cobra.Command) {
964-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s - Remote development on your infrastucture\n", cliui.Styles.Bold.Render("Coder "+buildinfo.Version()))
964+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s - Software development on your infrastucture\n", cliui.Styles.Bold.Render("Coder "+buildinfo.Version()))
965965
}
966966

967967
func loadCertificates(tlsCertFiles, tlsKeyFiles []string) ([]tls.Certificate, error) {

coderd/autobuild/executor/lifecycle_executor.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,14 @@ func (e *Executor) runOnce(t time.Time) Stats {
9999
// NOTE: If a workspace build is created with a given TTL and then the user either
100100
// changes or unsets the TTL, the deadline for the workspace build will not
101101
// have changed. This behavior is as expected per #2229.
102-
workspaces, err := e.db.GetWorkspaces(e.ctx, database.GetWorkspacesParams{
102+
workspaceRows, err := e.db.GetWorkspaces(e.ctx, database.GetWorkspacesParams{
103103
Deleted: false,
104104
})
105105
if err != nil {
106106
e.log.Error(e.ctx, "get workspaces for autostart or autostop", slog.Error(err))
107107
return stats
108108
}
109+
workspaces := database.ConvertWorkspaceRows(workspaceRows)
109110

110111
var eligibleWorkspaceIDs []uuid.UUID
111112
for _, ws := range workspaces {

coderd/database/databasefake/databasefake.go

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -718,14 +718,14 @@ func (q *fakeQuerier) GetAuthorizationUserRoles(_ context.Context, userID uuid.U
718718
}, nil
719719
}
720720

721-
func (q *fakeQuerier) GetWorkspaces(ctx context.Context, arg database.GetWorkspacesParams) ([]database.Workspace, error) {
721+
func (q *fakeQuerier) GetWorkspaces(ctx context.Context, arg database.GetWorkspacesParams) ([]database.GetWorkspacesRow, error) {
722722
// A nil auth filter means no auth filter.
723-
workspaces, err := q.GetAuthorizedWorkspaces(ctx, arg, nil)
724-
return workspaces, err
723+
workspaceRows, err := q.GetAuthorizedWorkspaces(ctx, arg, nil)
724+
return workspaceRows, err
725725
}
726726

727727
//nolint:gocyclo
728-
func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) ([]database.Workspace, error) {
728+
func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) ([]database.GetWorkspacesRow, error) {
729729
q.mutex.RLock()
730730
defer q.mutex.RUnlock()
731731

@@ -866,20 +866,43 @@ func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
866866
workspaces = append(workspaces, workspace)
867867
}
868868

869+
beforePageCount := len(workspaces)
870+
869871
if arg.Offset > 0 {
870872
if int(arg.Offset) > len(workspaces) {
871-
return []database.Workspace{}, nil
873+
return []database.GetWorkspacesRow{}, nil
872874
}
873875
workspaces = workspaces[arg.Offset:]
874876
}
875877
if arg.Limit > 0 {
876878
if int(arg.Limit) > len(workspaces) {
877-
return workspaces, nil
879+
return convertToWorkspaceRows(workspaces, int64(beforePageCount)), nil
878880
}
879881
workspaces = workspaces[:arg.Limit]
880882
}
881883

882-
return workspaces, nil
884+
return convertToWorkspaceRows(workspaces, int64(beforePageCount)), nil
885+
}
886+
887+
func convertToWorkspaceRows(workspaces []database.Workspace, count int64) []database.GetWorkspacesRow {
888+
rows := make([]database.GetWorkspacesRow, len(workspaces))
889+
for i, w := range workspaces {
890+
rows[i] = database.GetWorkspacesRow{
891+
ID: w.ID,
892+
CreatedAt: w.CreatedAt,
893+
UpdatedAt: w.UpdatedAt,
894+
OwnerID: w.OwnerID,
895+
OrganizationID: w.OrganizationID,
896+
TemplateID: w.TemplateID,
897+
Deleted: w.Deleted,
898+
Name: w.Name,
899+
AutostartSchedule: w.AutostartSchedule,
900+
Ttl: w.Ttl,
901+
LastUsedAt: w.LastUsedAt,
902+
Count: count,
903+
}
904+
}
905+
return rows
883906
}
884907

885908
func (q *fakeQuerier) GetWorkspaceByID(_ context.Context, id uuid.UUID) (database.Workspace, error) {

coderd/database/modelmethods.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,24 @@ func ConvertUserRows(rows []GetUsersRow) []User {
9393

9494
return users
9595
}
96+
97+
func ConvertWorkspaceRows(rows []GetWorkspacesRow) []Workspace {
98+
workspaces := make([]Workspace, len(rows))
99+
for i, r := range rows {
100+
workspaces[i] = Workspace{
101+
ID: r.ID,
102+
CreatedAt: r.CreatedAt,
103+
UpdatedAt: r.UpdatedAt,
104+
OwnerID: r.OwnerID,
105+
OrganizationID: r.OrganizationID,
106+
TemplateID: r.TemplateID,
107+
Deleted: r.Deleted,
108+
Name: r.Name,
109+
AutostartSchedule: r.AutostartSchedule,
110+
Ttl: r.Ttl,
111+
LastUsedAt: r.LastUsedAt,
112+
}
113+
}
114+
115+
return workspaces
116+
}

coderd/database/modelqueries.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,13 @@ func (q *sqlQuerier) GetTemplateGroupRoles(ctx context.Context, id uuid.UUID) ([
112112
}
113113

114114
type workspaceQuerier interface {
115-
GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) ([]Workspace, error)
115+
GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) ([]GetWorkspacesRow, error)
116116
}
117117

118118
// GetAuthorizedWorkspaces returns all workspaces that the user is authorized to access.
119119
// This code is copied from `GetWorkspaces` and adds the authorized filter WHERE
120120
// clause.
121-
func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) ([]Workspace, error) {
121+
func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspacesParams, authorizedFilter rbac.AuthorizeFilter) ([]GetWorkspacesRow, error) {
122122
// In order to properly use ORDER BY, OFFSET, and LIMIT, we need to inject the
123123
// authorizedFilter between the end of the where clause and those statements.
124124
filter := strings.Replace(getWorkspaces, "-- @authorize_filter", fmt.Sprintf(" AND %s", authorizedFilter.SQLString(rbac.NoACLConfig())), 1)
@@ -139,9 +139,9 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
139139
return nil, xerrors.Errorf("get authorized workspaces: %w", err)
140140
}
141141
defer rows.Close()
142-
var items []Workspace
142+
var items []GetWorkspacesRow
143143
for rows.Next() {
144-
var i Workspace
144+
var i GetWorkspacesRow
145145
if err := rows.Scan(
146146
&i.ID,
147147
&i.CreatedAt,
@@ -154,6 +154,7 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
154154
&i.AutostartSchedule,
155155
&i.Ttl,
156156
&i.LastUsedAt,
157+
&i.Count,
157158
); err != nil {
158159
return nil, err
159160
}

coderd/database/querier.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)