Skip to content

Commit bd701d9

Browse files
committed
handle post signed request
1 parent 4a8d9eb commit bd701d9

File tree

4 files changed

+85
-11
lines changed

4 files changed

+85
-11
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ require (
1414
github.com/go-logr/logr v1.4.3
1515
github.com/go-task/task/v3 v3.44.1
1616
github.com/joho/godotenv v1.5.1
17-
github.com/livekit/protocol v1.42.1-0.20250929175250-2ddfb3ee7f7e
17+
github.com/livekit/protocol v1.42.1-0.20251008181454-49a136864c2d
1818
github.com/livekit/server-sdk-go/v2 v2.11.3
1919
github.com/moby/buildkit v0.23.2
2020
github.com/moby/patternmatcher v0.6.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ github.com/livekit/mediatransportutil v0.0.0-20250825135402-7bc31f107ade h1:lpxP
276276
github.com/livekit/mediatransportutil v0.0.0-20250825135402-7bc31f107ade/go.mod h1:mSNtYzSf6iY9xM3UX42VEI+STHvMgHmrYzEHPcdhB8A=
277277
github.com/livekit/protocol v1.42.1-0.20250929175250-2ddfb3ee7f7e h1:yytr+uwFXtJ8UxBV2q3j55jVKg7zslECuGeE4F56NoU=
278278
github.com/livekit/protocol v1.42.1-0.20250929175250-2ddfb3ee7f7e/go.mod h1:vhMS30QoEyH2p34vi6X1eWkC4EMV72ZGZwQb74ajY7A=
279+
github.com/livekit/protocol v1.42.1-0.20251008181454-49a136864c2d h1:ofC+CPiYDZ4LD+RgIJg4rUFLvKnWJqg66bn00FALKLI=
280+
github.com/livekit/protocol v1.42.1-0.20251008181454-49a136864c2d/go.mod h1:vhMS30QoEyH2p34vi6X1eWkC4EMV72ZGZwQb74ajY7A=
279281
github.com/livekit/psrpc v0.7.0 h1:rtfqfjYN06WJYloE/S0nmkJ/Y04x4pxLQLe8kQ4FVHU=
280282
github.com/livekit/psrpc v0.7.0/go.mod h1:AuDC5uOoEjQJEc69v4Li3t77Ocz0e0NdjQEuFfO+vfk=
281283
github.com/livekit/server-sdk-go/v2 v2.11.3 h1:k+YDxo8wPCixRrS9fJHcbtlurlXhVLfyPva5Ne4tVH0=

pkg/agentfs/client.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
livekitcli "github.com/livekit/livekit-cli/v2"
2727
"github.com/livekit/protocol/auth"
28+
"github.com/livekit/protocol/livekit"
2829
lkproto "github.com/livekit/protocol/livekit"
2930
"github.com/livekit/protocol/logger"
3031
lksdk "github.com/livekit/server-sdk-go/v2"
@@ -111,7 +112,13 @@ func (c *Client) CreateAgent(
111112
if err != nil {
112113
return nil, err
113114
}
114-
if err := c.uploadAndBuild(ctx, resp.AgentId, resp.PresignedUrl, workingDir, excludeFiles); err != nil {
115+
if err := c.uploadAndBuild(ctx,
116+
resp.AgentId,
117+
resp.PresignedUrl,
118+
resp.PresignedPostRequest,
119+
workingDir,
120+
excludeFiles,
121+
); err != nil {
115122
return nil, err
116123
}
117124
return resp, nil
@@ -135,14 +142,15 @@ func (c *Client) DeployAgent(
135142
if !resp.Success {
136143
return fmt.Errorf("failed to deploy agent: %s", resp.Message)
137144
}
138-
return c.uploadAndBuild(ctx, agentID, resp.PresignedUrl, workingDir, excludeFiles)
145+
return c.uploadAndBuild(ctx, agentID, resp.PresignedUrl, resp.PresignedPostRequest, workingDir, excludeFiles)
139146
}
140147

141148
// uploadAndBuild uploads the source and triggers remote build
142149
func (c *Client) uploadAndBuild(
143150
ctx context.Context,
144151
agentID string,
145152
presignedUrl string,
153+
presignedPostRequest *livekit.PresignedPostRequest,
146154
workingDir string,
147155
excludeFiles []string,
148156
) error {
@@ -153,6 +161,7 @@ func (c *Client) uploadAndBuild(
153161
if err := UploadTarball(
154162
workingDir,
155163
presignedUrl,
164+
presignedPostRequest,
156165
excludeFiles,
157166
projectType,
158167
); err != nil {

pkg/agentfs/tar.go

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@ import (
2020
"compress/gzip"
2121
"fmt"
2222
"io"
23+
"mime/multipart"
2324
"net/http"
2425
"os"
2526
"path"
2627
"path/filepath"
2728
"strings"
2829

2930
"github.com/schollz/progressbar/v3"
31+
"golang.org/x/sync/errgroup"
3032

3133
"github.com/livekit/livekit-cli/v2/pkg/util"
34+
"github.com/livekit/protocol/livekit"
3235
"github.com/livekit/protocol/logger"
3336

3437
"github.com/moby/patternmatcher"
@@ -51,7 +54,13 @@ var (
5154
}
5255
)
5356

54-
func UploadTarball(directory string, presignedUrl string, excludeFiles []string, projectType ProjectType) error {
57+
func UploadTarball(
58+
directory string,
59+
presignedUrl string,
60+
presignedPostRequest *livekit.PresignedPostRequest,
61+
excludeFiles []string,
62+
projectType ProjectType,
63+
) error {
5564
excludeFiles = append(excludeFiles, defaultExcludePatterns...)
5665

5766
loadExcludeFiles := func(filename string) (bool, string, error) {
@@ -274,25 +283,79 @@ func UploadTarball(directory string, presignedUrl string, excludeFiles []string,
274283
}),
275284
)
276285

277-
req, err := http.NewRequest("PUT", presignedUrl, io.TeeReader(&buffer, uploadProgress))
286+
if presignedPostRequest != nil {
287+
if err := multipartUpload(presignedPostRequest.Url, presignedPostRequest.Values, &buffer, uploadProgress); err != nil {
288+
return fmt.Errorf("multipart upload failed: %w", err)
289+
}
290+
} else {
291+
if err := upload(presignedUrl, &buffer, uploadProgress); err != nil {
292+
return fmt.Errorf("upload failed: %w", err)
293+
}
294+
}
295+
296+
fmt.Println()
297+
return nil
298+
}
299+
300+
func upload(presignedUrl string, buffer *bytes.Buffer, uploadProgress *progressbar.ProgressBar) error {
301+
req, err := http.NewRequest("PUT", presignedUrl, io.TeeReader(buffer, uploadProgress))
278302
if err != nil {
279303
return fmt.Errorf("failed to create request: %w", err)
280304
}
281305
req.Header.Set("Content-Type", "application/gzip")
282306
req.ContentLength = int64(buffer.Len())
283-
284-
client := &http.Client{}
285-
resp, err := client.Do(req)
307+
resp, err := http.DefaultClient.Do(req)
286308
if err != nil {
287309
return fmt.Errorf("failed to upload tarball: %w", err)
288310
}
289311
defer resp.Body.Close()
290-
291312
if resp.StatusCode != http.StatusOK {
292313
body, _ := io.ReadAll(resp.Body)
293314
return fmt.Errorf("failed to upload tarball: %d: %s", resp.StatusCode, body)
294315
}
295-
296-
fmt.Println()
297316
return nil
298317
}
318+
319+
func multipartUpload(presignedURL string, fields map[string]string, buf *bytes.Buffer, uploadProgress *progressbar.ProgressBar) error {
320+
pr, pw := io.Pipe()
321+
w := multipart.NewWriter(pw)
322+
var eg errgroup.Group
323+
eg.Go(func() error {
324+
defer pw.Close()
325+
defer w.Close()
326+
for k, v := range fields {
327+
if err := w.WriteField(k, v); err != nil {
328+
pw.CloseWithError(err)
329+
return err
330+
}
331+
}
332+
part, err := w.CreateFormFile("file", "upload.tar.gz")
333+
if err != nil {
334+
pw.CloseWithError(err)
335+
return err
336+
}
337+
if _, err := io.Copy(part, io.TeeReader(buf, uploadProgress)); err != nil {
338+
pw.CloseWithError(err)
339+
return err
340+
}
341+
return nil
342+
})
343+
eg.Go(func() error {
344+
req, err := http.NewRequest("POST", presignedURL, pr)
345+
if err != nil {
346+
return err
347+
}
348+
req.Header.Set("Content-Type", w.FormDataContentType())
349+
resp, err := http.DefaultClient.Do(req)
350+
if err != nil {
351+
return err
352+
}
353+
defer resp.Body.Close()
354+
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
355+
respBody, _ := io.ReadAll(resp.Body)
356+
return fmt.Errorf("failed to upload tarball: %d: %s", resp.StatusCode, respBody)
357+
}
358+
return nil
359+
})
360+
return eg.Wait()
361+
}

0 commit comments

Comments
 (0)