1717package desktop
1818
1919import (
20- "bytes"
2120 "context"
2221 "encoding/json"
23- "errors"
2422 "fmt"
2523 "io"
2624 "net"
@@ -29,7 +27,6 @@ import (
2927
3028 "github.com/docker/compose/v2/internal"
3129 "github.com/docker/compose/v2/internal/memnet"
32- "github.com/r3labs/sse"
3330 "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
3431)
3532
@@ -130,212 +127,6 @@ func (c *Client) FeatureFlags(ctx context.Context) (FeatureFlagResponse, error)
130127 return ret , nil
131128}
132129
133- type GetFileSharesConfigResponse struct {
134- Active bool `json:"active"`
135- Compose struct {
136- ManageBindMounts bool `json:"manageBindMounts"`
137- }
138- }
139-
140- func (c * Client ) GetFileSharesConfig (ctx context.Context ) (* GetFileSharesConfigResponse , error ) {
141- req , err := c .newRequest (ctx , http .MethodGet , "/mutagen/file-shares/config" , http .NoBody )
142- if err != nil {
143- return nil , err
144- }
145-
146- resp , err := c .client .Do (req )
147- if err != nil {
148- return nil , err
149- }
150- defer func () {
151- _ = resp .Body .Close ()
152- }()
153-
154- if resp .StatusCode != http .StatusOK {
155- return nil , newHTTPStatusCodeError (resp )
156- }
157-
158- var ret GetFileSharesConfigResponse
159- if err := json .NewDecoder (resp .Body ).Decode (& ret ); err != nil {
160- return nil , err
161- }
162- return & ret , nil
163- }
164-
165- type CreateFileShareRequest struct {
166- HostPath string `json:"hostPath"`
167- Labels map [string ]string `json:"labels,omitempty"`
168- }
169-
170- type CreateFileShareResponse struct {
171- FileShareID string `json:"fileShareID"`
172- }
173-
174- func (c * Client ) CreateFileShare (ctx context.Context , r CreateFileShareRequest ) (* CreateFileShareResponse , error ) {
175- rawBody , err := json .Marshal (r )
176- if err != nil {
177- return nil , fmt .Errorf ("failed to marshal request: %w" , err )
178- }
179-
180- req , err := c .newRequest (ctx , http .MethodPost , "/mutagen/file-shares" , bytes .NewReader (rawBody ))
181- if err != nil {
182- return nil , err
183- }
184- req .Header .Set ("Content-Type" , "application/json" )
185-
186- resp , err := c .client .Do (req )
187- if err != nil {
188- return nil , err
189- }
190- defer func () {
191- _ = resp .Body .Close ()
192- }()
193-
194- if resp .StatusCode != http .StatusOK {
195- errBody , _ := io .ReadAll (resp .Body )
196- return nil , fmt .Errorf ("unexpected status code %d: %s" , resp .StatusCode , string (errBody ))
197- }
198-
199- var ret CreateFileShareResponse
200- if err := json .NewDecoder (resp .Body ).Decode (& ret ); err != nil {
201- return nil , err
202- }
203- return & ret , nil
204- }
205-
206- type FileShareReceiverState struct {
207- TotalReceivedSize uint64 `json:"totalReceivedSize"`
208- }
209-
210- type FileShareEndpoint struct {
211- Path string `json:"path"`
212- TotalFileSize uint64 `json:"totalFileSize,omitempty"`
213- StagingProgress * FileShareReceiverState `json:"stagingProgress"`
214- }
215-
216- type FileShareSession struct {
217- SessionID string `json:"identifier"`
218- Alpha FileShareEndpoint `json:"alpha"`
219- Beta FileShareEndpoint `json:"beta"`
220- Labels map [string ]string `json:"labels"`
221- Status string `json:"status"`
222- }
223-
224- func (c * Client ) ListFileShares (ctx context.Context ) ([]FileShareSession , error ) {
225- req , err := c .newRequest (ctx , http .MethodGet , "/mutagen/file-shares" , http .NoBody )
226- if err != nil {
227- return nil , err
228- }
229-
230- resp , err := c .client .Do (req )
231- if err != nil {
232- return nil , err
233- }
234- defer func () {
235- _ = resp .Body .Close ()
236- }()
237-
238- if resp .StatusCode != http .StatusOK {
239- return nil , newHTTPStatusCodeError (resp )
240- }
241-
242- var ret []FileShareSession
243- if err := json .NewDecoder (resp .Body ).Decode (& ret ); err != nil {
244- return nil , err
245- }
246- return ret , nil
247- }
248-
249- func (c * Client ) DeleteFileShare (ctx context.Context , id string ) error {
250- req , err := c .newRequest (ctx , http .MethodDelete , "/mutagen/file-shares/" + id , http .NoBody )
251- if err != nil {
252- return err
253- }
254-
255- resp , err := c .client .Do (req )
256- if err != nil {
257- return err
258- }
259- defer func () {
260- _ = resp .Body .Close ()
261- }()
262-
263- if resp .StatusCode < 200 || resp .StatusCode >= 300 {
264- return newHTTPStatusCodeError (resp )
265- }
266- return nil
267- }
268-
269- type EventMessage [T any ] struct {
270- Value T
271- Error error
272- }
273-
274- func newHTTPStatusCodeError (resp * http.Response ) error {
275- r := io .LimitReader (resp .Body , 2048 )
276- body , err := io .ReadAll (r )
277- if err != nil {
278- return fmt .Errorf ("http status code %d" , resp .StatusCode )
279- }
280- return fmt .Errorf ("http status code %d: %s" , resp .StatusCode , string (body ))
281- }
282-
283- func (c * Client ) StreamFileShares (ctx context.Context ) (<- chan EventMessage [[]FileShareSession ], error ) {
284- req , err := c .newRequest (ctx , http .MethodGet , "/mutagen/file-shares/stream" , http .NoBody )
285- if err != nil {
286- return nil , err
287- }
288-
289- resp , err := c .client .Do (req )
290- if err != nil {
291- return nil , err
292- }
293-
294- if resp .StatusCode < 200 || resp .StatusCode >= 300 {
295- _ = resp .Body .Close ()
296- return nil , newHTTPStatusCodeError (resp )
297- }
298-
299- events := make (chan EventMessage [[]FileShareSession ])
300- go func (ctx context.Context ) {
301- defer func () {
302- _ = resp .Body .Close ()
303- close (events )
304- }()
305- if err := readEvents (ctx , resp .Body , events ); err != nil {
306- select {
307- case <- ctx .Done ():
308- case events <- EventMessage [[]FileShareSession ]{Error : err }:
309- }
310- }
311- }(ctx )
312- return events , nil
313- }
314-
315- func readEvents [T any ](ctx context.Context , r io.Reader , events chan <- EventMessage [T ]) error {
316- eventReader := sse .NewEventStreamReader (r )
317- for {
318- msg , err := eventReader .ReadEvent ()
319- if errors .Is (err , io .EOF ) {
320- return nil
321- } else if err != nil {
322- return fmt .Errorf ("reading events: %w" , err )
323- }
324- msg = bytes .TrimPrefix (msg , []byte ("data: " ))
325-
326- var event T
327- if err := json .Unmarshal (msg , & event ); err != nil {
328- return err
329- }
330- select {
331- case <- ctx .Done ():
332- return context .Cause (ctx )
333- case events <- EventMessage [T ]{Value : event }:
334- // event was sent to channel, read next
335- }
336- }
337- }
338-
339130func (c * Client ) newRequest (ctx context.Context , method , path string , body io.Reader ) (* http.Request , error ) {
340131 req , err := http .NewRequestWithContext (ctx , method , backendURL (path ), body )
341132 if err != nil {
0 commit comments