Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aa4c8ac

Browse files
committed
Merge branch 'main' into singletemplate
2 parents a825ece + 4eb0bb6 commit aa4c8ac

File tree

11 files changed

+179
-39
lines changed

11 files changed

+179
-39
lines changed

.goreleaser.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ docker_manifests:
153153

154154
release:
155155
ids: [coder-linux, coder-darwin, coder-windows, packages]
156+
footer: |
157+
## Container Image
158+
- `docker pull ghcr.io/coder/coder:{{ .Tag }}`
156159
157160
signs:
158161
- ids: [coder-darwin]

coderd/autobuild/executor/lifecycle_executor_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"strings"
78
"testing"
89
"time"
910

@@ -470,6 +471,9 @@ func mustTransitionWorkspace(t *testing.T, client *codersdk.Client, workspaceID
470471
func mustWorkspace(t *testing.T, client *codersdk.Client, workspaceID uuid.UUID) codersdk.Workspace {
471472
ctx := context.Background()
472473
ws, err := client.Workspace(ctx, workspaceID)
474+
if err != nil && strings.Contains(err.Error(), "status code 410") {
475+
ws, err = client.DeletedWorkspace(ctx, workspaceID)
476+
}
473477
require.NoError(t, err, "no workspace found with id %s", workspaceID)
474478
return ws
475479
}

coderd/workspaces.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"errors"
88
"fmt"
99
"net/http"
10+
"strconv"
1011
"time"
1112

1213
"github.com/go-chi/chi/v5"
@@ -34,6 +35,40 @@ func (api *api) workspace(rw http.ResponseWriter, r *http.Request) {
3435
return
3536
}
3637

38+
if !api.Authorize(rw, r, rbac.ActionRead,
39+
rbac.ResourceWorkspace.InOrg(workspace.OrganizationID).WithOwner(workspace.OwnerID.String()).WithID(workspace.ID.String())) {
40+
return
41+
}
42+
43+
// The `deleted` query parameter (which defaults to `false`) MUST match the
44+
// `Deleted` field on the workspace otherwise you will get a 410 Gone.
45+
var (
46+
deletedStr = r.URL.Query().Get("deleted")
47+
showDeleted = false
48+
)
49+
if deletedStr != "" {
50+
var err error
51+
showDeleted, err = strconv.ParseBool(deletedStr)
52+
if err != nil {
53+
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
54+
Message: fmt.Sprintf("invalid bool for 'deleted' query param: %s", err),
55+
})
56+
return
57+
}
58+
}
59+
if workspace.Deleted && !showDeleted {
60+
httpapi.Write(rw, http.StatusGone, httpapi.Response{
61+
Message: fmt.Sprintf("workspace %q was deleted, you can view this workspace by specifying '?deleted=true' and trying again", workspace.ID.String()),
62+
})
63+
return
64+
}
65+
if !workspace.Deleted && showDeleted {
66+
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
67+
Message: fmt.Sprintf("workspace %q is not deleted, please remove '?deleted=true' and try again", workspace.ID.String()),
68+
})
69+
return
70+
}
71+
3772
build, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(r.Context(), workspace.ID)
3873
if err != nil {
3974
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{

coderd/workspaces_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,58 @@ import (
2020
"github.com/coder/coder/provisionersdk/proto"
2121
)
2222

23+
func TestWorkspace(t *testing.T) {
24+
t.Parallel()
25+
26+
t.Run("OK", func(t *testing.T) {
27+
t.Parallel()
28+
client := coderdtest.New(t, nil)
29+
user := coderdtest.CreateFirstUser(t, client)
30+
coderdtest.NewProvisionerDaemon(t, client)
31+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
32+
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
33+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
34+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
35+
36+
_, err := client.Workspace(context.Background(), workspace.ID)
37+
require.NoError(t, err)
38+
})
39+
40+
t.Run("Deleted", func(t *testing.T) {
41+
t.Parallel()
42+
client := coderdtest.New(t, nil)
43+
user := coderdtest.CreateFirstUser(t, client)
44+
coderdtest.NewProvisionerDaemon(t, client)
45+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
46+
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
47+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
48+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
49+
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
50+
51+
// Getting with deleted=true should fail.
52+
_, err := client.DeletedWorkspace(context.Background(), workspace.ID)
53+
require.Error(t, err)
54+
require.ErrorContains(t, err, "400") // bad request
55+
56+
// Delete the workspace
57+
build, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
58+
Transition: database.WorkspaceTransitionDelete,
59+
})
60+
require.NoError(t, err, "delete the workspace")
61+
coderdtest.AwaitWorkspaceBuildJob(t, client, build.ID)
62+
63+
// Getting with deleted=true should work.
64+
workspaceNew, err := client.DeletedWorkspace(context.Background(), workspace.ID)
65+
require.NoError(t, err)
66+
require.Equal(t, workspace.ID, workspaceNew.ID)
67+
68+
// Getting with deleted=false should not work.
69+
_, err = client.Workspace(context.Background(), workspace.ID)
70+
require.Error(t, err)
71+
require.ErrorContains(t, err, "410") // gone
72+
})
73+
}
74+
2375
func TestAdminViewAllWorkspaces(t *testing.T) {
2476
t.Parallel()
2577
client := coderdtest.New(t, nil)

codersdk/client.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ type Client struct {
3636

3737
type requestOption func(*http.Request)
3838

39+
func queryParam(k, v string) requestOption {
40+
return func(r *http.Request) {
41+
q := r.URL.Query()
42+
q.Set(k, v)
43+
r.URL.RawQuery = q.Encode()
44+
}
45+
}
46+
3947
// Request performs an HTTP request with the body provided.
4048
// The caller is responsible for closing the response body.
4149
func (c *Client) Request(ctx context.Context, method, path string, body interface{}, opts ...requestOption) (*http.Response, error) {

codersdk/workspaces.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,16 @@ type CreateWorkspaceBuildRequest struct {
4242

4343
// Workspace returns a single workspace.
4444
func (c *Client) Workspace(ctx context.Context, id uuid.UUID) (Workspace, error) {
45-
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s", id), nil)
45+
return c.getWorkspace(ctx, id)
46+
}
47+
48+
// DeletedWorkspace returns a single workspace that was deleted.
49+
func (c *Client) DeletedWorkspace(ctx context.Context, id uuid.UUID) (Workspace, error) {
50+
return c.getWorkspace(ctx, id, queryParam("deleted", "true"))
51+
}
52+
53+
func (c *Client) getWorkspace(ctx context.Context, id uuid.UUID, opts ...requestOption) (Workspace, error) {
54+
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s", id), nil, opts...)
4655
if err != nil {
4756
return Workspace{}, err
4857
}

docs/README.md

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,52 +20,69 @@ Provision remote development environments with Terraform.
2020

2121
## Installing Coder
2222

23-
Install [the latest release](https://github.com/coder/coder/releases) on a system with
24-
at least 1 CPU core and 2 GB RAM.
23+
We recommend installing [the latest
24+
release](https://github.com/coder/coder/releases) on a system with at least 1
25+
CPU core and 2 GB RAM:
2526

26-
To test, start with dev mode (all data is in-memory and is destroyed on exit):
27+
1. Download the release appropriate for your operating system
28+
1. Unzip the folder you just downloaded, and move the `coder` executable to a
29+
location that's on your `PATH`
2730

28-
```bash
29-
coder server --dev
30-
```
31+
> Make sure you have the appropriate credentials for your cloud provider (e.g.,
32+
> access key ID and secret access key for AWS).
3133
32-
To run a production deployment with PostgreSQL:
34+
You can set up a temporary deployment, a production deployment, or a system service:
3335

34-
```bash
35-
CODER_PG_CONNECTION_URL="postgres://<username>@<host>/<database>?password=<password>" \
36-
coder server
37-
```
36+
- To set up a **temporary deployment**, start with dev mode (all data is in-memory and is
37+
destroyed on exit):
38+
39+
```bash
40+
coder server --dev
41+
```
42+
43+
- To run a **production deployment** with PostgreSQL:
44+
45+
```bash
46+
CODER_PG_CONNECTION_URL="postgres://<username>@<host>/<database>?password=<password>" \
47+
coder server
48+
```
3849

39-
To run as a system service, install with `.deb` (Debian, Ubuntu) or `.rpm`
50+
- To run as a **system service**, install with `.deb` (Debian, Ubuntu) or `.rpm`
4051
(Fedora, CentOS, RHEL, SUSE):
4152

42-
```bash
43-
# Edit the configuration!
44-
sudo vim /etc/coder.d/coder.env
45-
sudo service coder restart
46-
```
53+
```bash
54+
# Edit the configuration!
55+
sudo vim /etc/coder.d/coder.env
56+
sudo service coder restart
57+
```
4758

48-
Use `coder start --help` to get a complete list of flags and environment
59+
> Use `coder --help` to get a complete list of flags and environment
4960
variables.
5061

51-
### Your first workspace
62+
## Creating your first template and workspace
5263

53-
In a new terminal, create a template (e.g., a template to **Develop in Linux on
54-
Google Cloud**):
64+
In a new terminal window, run the following to copy a sample template:
5565

5666
```bash
5767
coder templates init
58-
coder templates create
5968
```
6069

61-
Create a workspace and connect to it via SSH:
70+
Follow the CLI instructions to modify and create the template specific for your
71+
usage (e.g., a template to **Develop in Linux on Google Cloud**).
72+
73+
Create a workspace using your template:
74+
75+
```bash
76+
coder create --template="yourTemplate" <workspaceName>
77+
```
78+
79+
Connect to your workspace via SSH:
6280

6381
```bash
64-
coder create my-first-workspace
65-
coder ssh my-first-workspace
82+
coder ssh <workspaceName>
6683
```
6784

68-
### Modifying templates
85+
## Modifying templates
6986

7087
You can edit the Terraform template using a sample template:
7188

docs/templates.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ to everybody. Users can also manually update their workspaces.
99

1010
## Manage templates
1111

12-
Coder provides production-ready [sample template](../examples/), but you can
12+
Coder provides production-ready [sample templates](../examples/), but you can
1313
modify the templates with Terraform.
1414

1515
```sh

docs/workspaces.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ templates](./templates.md):
1212
# create a workspace from the template; specify any variables
1313
coder create <workspace-name>
1414

15-
# show the resources behind the workspace, and how to connect
15+
# show the resources behind the workspace and how to connect
1616
coder show <workspace-name>
1717
```
1818

@@ -23,8 +23,7 @@ IDE with remote development support:
2323

2424
```sh
2525
coder config-ssh
26-
27-
ssh coder.<workspace-name>
26+
coder ssh <workspaceName>
2827
```
2928

3029
## Editors and IDEs
@@ -61,7 +60,7 @@ resources](./templates.md#persistent-and-ephemeral-resources).
6160
> where to store files, install software, etc., so that they persist. Default
6261
> templates are documented in [../examples](../examples/).
6362
>
64-
> You can use `coder workspace show <workspace-name>` to see which resources are
63+
> You can use `coder show <workspace-name>` to see which resources are
6564
> persistent and which are ephemeral.
6665
6766
When a workspace is deleted, all of the workspace's resources are deleted.

provisionersdk/agent.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,28 @@ $env:CODER_AGENT_URL = "${ACCESS_URL}"
1717
Start-Process -FilePath $env:TEMP\sshd.exe -ArgumentList "agent" -PassThru`
1818

1919
linuxScript = `#!/usr/bin/env sh
20-
set -eu pipefail
21-
export BINARY_LOCATION=$(mktemp -d -t tmp.coderXXXXX)/coder
22-
curl -fsSL ${ACCESS_URL}bin/coder-linux-${ARCH} -o $BINARY_LOCATION
20+
set -eux pipefail
21+
BINARY_LOCATION=$(mktemp -d -t tmp.coderXXXXXX)/coder
22+
BINARY_URL=${ACCESS_URL}bin/coder-linux-${ARCH}
23+
if which curl >/dev/null 2>&1; then
24+
curl -fsSL "${BINARY_URL}" -o "${BINARY_LOCATION}"
25+
elif which wget >/dev/null 2>&1; then
26+
wget -q "${BINARY_URL}" -O "${BINARY_LOCATION}"
27+
elif which busybox >/dev/null 2>&1; then
28+
busybox wget -q "${BINARY_URL}" -O "${BINARY_LOCATION}"
29+
else
30+
echo "error: no download tool found, please install curl, wget or busybox wget"
31+
exit 1
32+
fi
2333
chmod +x $BINARY_LOCATION
2434
export CODER_AGENT_AUTH="${AUTH_TYPE}"
2535
export CODER_AGENT_URL="${ACCESS_URL}"
2636
exec $BINARY_LOCATION agent`
2737

2838
darwinScript = `#!/usr/bin/env sh
29-
set -eu pipefail
30-
export BINARY_LOCATION=$(mktemp -d -t tmp.coderXXXXX)/coder
31-
curl -fsSL ${ACCESS_URL}bin/coder-darwin-${ARCH} -o $BINARY_LOCATION
39+
set -eux pipefail
40+
BINARY_LOCATION=$(mktemp -d -t tmp.coderXXXXXX)/coder
41+
curl -fsSL "${ACCESS_URL}bin/coder-darwin-${ARCH}" -o "${BINARY_LOCATION}"
3242
chmod +x $BINARY_LOCATION
3343
export CODER_AGENT_AUTH="${AUTH_TYPE}"
3444
export CODER_AGENT_URL="${ACCESS_URL}"

provisionersdk/agent_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,11 @@ func TestAgentScript(t *testing.T) {
4949
output, err := exec.Command("sh", "-c", script).CombinedOutput()
5050
t.Log(string(output))
5151
require.NoError(t, err)
52+
// Ignore debug output from `set -x`, we're only interested in the last line.
53+
lines := strings.Split(strings.TrimSpace(string(output)), "\n")
54+
lastLine := lines[len(lines)-1]
5255
// Because we use the "echo" binary, we should expect the arguments provided
5356
// as the response to executing our script.
54-
require.Equal(t, "agent", strings.TrimSpace(string(output)))
57+
require.Equal(t, "agent", lastLine)
5558
})
5659
}

0 commit comments

Comments
 (0)