Skip to content

Commit da855c9

Browse files
committed
Merge remote-tracking branch 'origin/main' into cli-fix
2 parents e8a8fb6 + f88f273 commit da855c9

File tree

20 files changed

+725
-279
lines changed

20 files changed

+725
-279
lines changed

cli/templatepush.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,13 @@ func (pf *templateUploadFlags) templateName(args []string) (string, error) {
8585
if len(args) > 0 {
8686
return args[0], nil
8787
}
88+
// Have to take absPath to resolve "." and "..".
89+
absPath, err := filepath.Abs(pf.directory)
90+
if err != nil {
91+
return "", err
92+
}
8893
// If no name is provided, use the directory name.
89-
return filepath.Base(pf.directory), nil
94+
return filepath.Base(absPath), nil
9095
}
9196

9297
func (r *RootCmd) templatePush() *clibase.Cmd {

cli/templatepush_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,9 @@ func TestTemplatePush(t *testing.T) {
155155
require.Equal(t, "example", templateVersions[1].Name)
156156
})
157157

158+
// This test modifies the working directory.
159+
//nolint:paralleltest
158160
t.Run("UseWorkingDir", func(t *testing.T) {
159-
t.Parallel()
160161
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
161162
user := coderdtest.CreateFirstUser(t, client)
162163
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@@ -173,9 +174,18 @@ func TestTemplatePush(t *testing.T) {
173174
r.Name = filepath.Base(source)
174175
})
175176

177+
oldDir, err := os.Getwd()
178+
require.NoError(t, err)
179+
180+
os.Chdir(source)
181+
182+
t.Cleanup(func() {
183+
os.Chdir(oldDir)
184+
})
185+
176186
// Don't pass the name of the template, it should use the
177187
// directory of the source.
178-
inv, root := clitest.New(t, "templates", "push", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho))
188+
inv, root := clitest.New(t, "templates", "push", "--test.provisioner", string(database.ProvisionerTypeEcho))
179189
clitest.SetupConfig(t, client, root)
180190
pty := ptytest.New(t).Attach(inv)
181191

coderd/provisionerjobs.go

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,47 @@ func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job
5454
}
5555
}
5656

57+
if !follow {
58+
logs, err := api.Database.GetProvisionerLogsAfterID(ctx, database.GetProvisionerLogsAfterIDParams{
59+
JobID: job.ID,
60+
CreatedAfter: after,
61+
})
62+
if errors.Is(err, sql.ErrNoRows) {
63+
err = nil
64+
}
65+
if err != nil {
66+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
67+
Message: "Internal error fetching provisioner logs.",
68+
Detail: err.Error(),
69+
})
70+
return
71+
}
72+
if logs == nil {
73+
logs = []database.ProvisionerJobLog{}
74+
}
75+
76+
logger.Debug(ctx, "Finished non-follow job logs")
77+
httpapi.Write(ctx, rw, http.StatusOK, convertProvisionerJobLogs(logs))
78+
return
79+
}
80+
81+
// if we are following logs, start the subscription before we query the database, so that we don't miss any logs
82+
// between the end of our query and the start of the subscription. We might get duplicates, so we'll keep track
83+
// of processed IDs.
84+
var bufferedLogs <-chan *database.ProvisionerJobLog
85+
if follow {
86+
bl, closeFollow, err := api.followProvisionerJobLogs(actor, job.ID)
87+
if err != nil {
88+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
89+
Message: "Internal error watching provisioner logs.",
90+
Detail: err.Error(),
91+
})
92+
return
93+
}
94+
defer closeFollow()
95+
bufferedLogs = bl
96+
}
97+
5798
logs, err := api.Database.GetProvisionerLogsAfterID(ctx, database.GetProvisionerLogsAfterIDParams{
5899
JobID: job.ID,
59100
CreatedAfter: after,
@@ -72,12 +113,6 @@ func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job
72113
logs = []database.ProvisionerJobLog{}
73114
}
74115

75-
if !follow {
76-
logger.Debug(ctx, "Finished non-follow job logs")
77-
httpapi.Write(ctx, rw, http.StatusOK, convertProvisionerJobLogs(logs))
78-
return
79-
}
80-
81116
api.WebsocketWaitMutex.Lock()
82117
api.WebsocketWaitGroup.Add(1)
83118
api.WebsocketWaitMutex.Unlock()
@@ -106,28 +141,19 @@ func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job
106141
return
107142
}
108143
}
144+
job, err = api.Database.GetProvisionerJobByID(ctx, job.ID)
145+
if err != nil {
146+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
147+
Message: "Internal error fetching provisioner job.",
148+
Detail: err.Error(),
149+
})
150+
return
151+
}
109152
if job.CompletedAt.Valid {
110153
// job was complete before we queried the database for historical logs
111154
return
112155
}
113156

114-
// if we are following logs, start the subscription before we query the database, so that we don't miss any logs
115-
// between the end of our query and the start of the subscription. We might get duplicates, so we'll keep track
116-
// of processed IDs.
117-
var bufferedLogs <-chan *database.ProvisionerJobLog
118-
if follow {
119-
bl, closeFollow, err := api.followProvisionerJobLogs(actor, job.ID)
120-
if err != nil {
121-
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
122-
Message: "Internal error watching provisioner logs.",
123-
Detail: err.Error(),
124-
})
125-
return
126-
}
127-
defer closeFollow()
128-
bufferedLogs = bl
129-
}
130-
131157
for {
132158
select {
133159
case <-ctx.Done():

coderd/templateversions.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ func (api *API) patchTemplateVersion(rw http.ResponseWriter, r *http.Request) {
123123
if errors.Is(err, errTemplateVersionNameConflict) {
124124
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
125125
Message: err.Error(),
126+
Validations: []codersdk.ValidationError{
127+
{Field: "name", Detail: "Name is already used"},
128+
},
126129
})
127130
return
128131
}

codersdk/organizations.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ func (c *Client) TemplatesByOrganization(ctx context.Context, organizationID uui
221221

222222
// TemplateByName finds a template inside the organization provided with a case-insensitive name.
223223
func (c *Client) TemplateByName(ctx context.Context, organizationID uuid.UUID, name string) (Template, error) {
224+
if name == "" {
225+
return Template{}, xerrors.Errorf("template name cannot be empty")
226+
}
224227
res, err := c.Request(ctx, http.MethodGet,
225228
fmt.Sprintf("/api/v2/organizations/%s/templates/%s", organizationID.String(), name),
226229
nil,

examples/templates/fly-docker-image/main.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ resource "coder_agent" "main" {
281281
sudo hostname -b "${data.coder_workspace.me.name}-fly"
282282
# Install the Fly CLI and add it to the PATH
283283
curl -L https://fly.io/install.sh | sh
284-
echo "export PATH=\$PATH:/home/coder/.fly" >> ~/.bashrc
284+
echo "export PATH=$PATH:/home/coder/.fly/bin" >> ~/.bashrc
285+
source ~/.bashrc
285286
EOT
286287
}
287288

go.mod

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ replace github.com/tcnksm/go-httpstat => github.com/kylecarbs/go-httpstat v0.0.0
3838

3939
// There are a few minor changes we make to Tailscale that we're slowly upstreaming. Compare here:
4040
// https://github.com/tailscale/tailscale/compare/main...coder:tailscale:main
41-
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20230321171725-fed359a0cafa
41+
replace tailscale.com => github.com/coder/tailscale v1.1.1-0.20230327205451-058fa46a3723
4242

4343
// Switch to our fork that imports fixes from http://github.com/tailscale/ssh.
4444
// See: https://github.com/coder/coder/issues/3371
@@ -58,7 +58,6 @@ require (
5858
github.com/AlecAivazis/survey/v2 v2.3.5
5959
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
6060
github.com/adrg/xdg v0.4.0
61-
github.com/ammario/prefixsuffix v0.0.0-20200405191514-5a0456bf2cfd
6261
github.com/andybalholm/brotli v1.0.4
6362
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
6463
github.com/awalterschulze/gographviz v2.0.3+incompatible
@@ -159,7 +158,6 @@ require (
159158
golang.org/x/sync v0.1.0
160159
golang.org/x/sys v0.6.0
161160
golang.org/x/term v0.5.0
162-
golang.org/x/text v0.7.0
163161
golang.org/x/tools v0.6.0
164162
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
165163
golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675
@@ -190,6 +188,7 @@ require (
190188
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
191189
github.com/modern-go/reflect2 v1.0.2 // indirect
192190
github.com/muesli/cancelreader v0.2.2 // indirect
191+
golang.org/x/text v0.7.0 // indirect
193192
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230215201556-9c5414ab4bde // indirect
194193
)
195194

go.sum

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,6 @@ github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1L
193193
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
194194
github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk=
195195
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
196-
github.com/ammario/prefixsuffix v0.0.0-20200405191514-5a0456bf2cfd h1:WOzjyD34+0vVw3wzE7js8Yvzo08ljzvK1jG6wL8elVU=
197-
github.com/ammario/prefixsuffix v0.0.0-20200405191514-5a0456bf2cfd/go.mod h1:VM1c/0Tl3O26UkHMbU32VFqLwLvi2FA40b6s5vPOpoo=
198196
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
199197
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
200198
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
@@ -380,8 +378,8 @@ github.com/coder/retry v1.3.1-0.20230210155434-e90a2e1e091d h1:09JG37IgTB6n3ouX9
380378
github.com/coder/retry v1.3.1-0.20230210155434-e90a2e1e091d/go.mod h1:r+1J5i/989wt6CUeNSuvFKKA9hHuKKPMxdzDbTuvwwk=
381379
github.com/coder/ssh v0.0.0-20220811105153-fcea99919338 h1:tN5GKFT68YLVzJoA8AHuiMNJ0qlhoD3pGN3JY9gxSko=
382380
github.com/coder/ssh v0.0.0-20220811105153-fcea99919338/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914=
383-
github.com/coder/tailscale v1.1.1-0.20230321171725-fed359a0cafa h1:EjRGgTz7BUECmbV8jHTi1/rKdDjJESGSlm1Jp7evvCQ=
384-
github.com/coder/tailscale v1.1.1-0.20230321171725-fed359a0cafa/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
381+
github.com/coder/tailscale v1.1.1-0.20230327205451-058fa46a3723 h1:TIEdewTbti0kTXo6kgKpF1MD3w+RYH+BZfkD1BqVB8c=
382+
github.com/coder/tailscale v1.1.1-0.20230327205451-058fa46a3723/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
385383
github.com/coder/terraform-provider-coder v0.6.21 h1:TIH6+/VQFreT8q/CkRvpHtbIeM5cOAhuDS5Sh1Nm21Q=
386384
github.com/coder/terraform-provider-coder v0.6.21/go.mod h1:UIfU3bYNeSzJJvHyJ30tEKjD6Z9utloI+HUM/7n94CY=
387385
github.com/coder/wgtunnel v0.1.5 h1:WP3sCj/3iJ34eKvpMQEp1oJHvm24RYh0NHbj1kfUKfs=

provisioner/terraform/resources_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,11 @@ func TestConvertResources(t *testing.T) {
380380
require.NoError(t, err)
381381
require.Equal(t, expectedNoMetadataMap, resourcesMap)
382382

383-
if expected.parameters == nil {
384-
expected.parameters = []*proto.RichParameter{}
383+
expectedParams := expected.parameters
384+
if expectedParams == nil {
385+
expectedParams = []*proto.RichParameter{}
385386
}
386-
parametersWant, err := json.Marshal(expected.parameters)
387+
parametersWant, err := json.Marshal(expectedParams)
387388
require.NoError(t, err)
388389
parametersGot, err := json.Marshal(state.Parameters)
389390
require.NoError(t, err)

site/src/api/api.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,17 @@ export const updateActiveTemplateVersion = async (
373373
return response.data
374374
}
375375

376+
export const patchTemplateVersion = async (
377+
templateVersionId: string,
378+
data: TypesGen.PatchTemplateVersionRequest,
379+
) => {
380+
const response = await axios.patch<TypesGen.TemplateVersion>(
381+
`/api/v2/templateversions/${templateVersionId}`,
382+
data,
383+
)
384+
return response.data
385+
}
386+
376387
export const updateTemplateMeta = async (
377388
templateId: string,
378389
data: TypesGen.UpdateTemplateMeta,
@@ -1020,3 +1031,26 @@ const getMissingParameters = (
10201031

10211032
return missingParameters
10221033
}
1034+
1035+
export const watchBuildLogs = (
1036+
versionId: string,
1037+
onMessage: (log: TypesGen.ProvisionerJobLog) => void,
1038+
) => {
1039+
return new Promise<void>((resolve, reject) => {
1040+
const proto = location.protocol === "https:" ? "wss:" : "ws:"
1041+
const socket = new WebSocket(
1042+
`${proto}//${location.host}/api/v2/templateversions/${versionId}/logs?follow=true`,
1043+
)
1044+
socket.binaryType = "blob"
1045+
socket.addEventListener("message", (event) =>
1046+
onMessage(JSON.parse(event.data) as TypesGen.ProvisionerJobLog),
1047+
)
1048+
socket.addEventListener("error", () => {
1049+
reject(new Error("Connection for logs failed."))
1050+
})
1051+
socket.addEventListener("close", () => {
1052+
// When the socket closes, logs have finished streaming!
1053+
resolve()
1054+
})
1055+
})
1056+
}

0 commit comments

Comments
 (0)