Skip to content

Commit f5884e7

Browse files
committed
Write files to volume
Signed-off-by: David Gageot <[email protected]>
1 parent ae0df99 commit f5884e7

File tree

3 files changed

+80
-30
lines changed

3 files changed

+80
-30
lines changed
Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package commands
22

33
import (
4+
"bytes"
45
"context"
6+
"encoding/base64"
57
"encoding/json"
68
"fmt"
79
"io"
@@ -11,43 +13,66 @@ import (
1113
"github.com/spf13/cobra"
1214
)
1315

16+
type FileContent struct {
17+
VolumeId string `json:"volumeId"`
18+
TargetPath string `json:"targetPath"`
19+
Contents string `json:"contents"`
20+
}
21+
1422
func ReadFromVolume(ctx context.Context) *cobra.Command {
1523
return &cobra.Command{
1624
Use: "read-from-volume",
1725
Short: "Read a file from the extension's volume",
1826
Args: cobra.ExactArgs(1),
1927
RunE: func(cmd *cobra.Command, args []string) error {
20-
content, err := readConfig(ctx, args[0])
21-
if err != nil {
28+
filename := args[0]
29+
30+
var content FileContent
31+
if err := get(ctx, httpClient(), "/volume-file-content?volumeId=docker-prompts&targetPath="+filename, &content); err != nil {
2232
return err
2333
}
24-
fmt.Print(content)
34+
35+
fmt.Print(content.Contents)
2536
return nil
2637
},
2738
}
2839
}
2940

30-
func readConfig(ctx context.Context, filename string) (string, error) {
31-
httpClient := &http.Client{
41+
func WriteToVolume(ctx context.Context) *cobra.Command {
42+
return &cobra.Command{
43+
Use: "write-to-volume",
44+
Short: "Write some base64 encoded content to a file on the extension's volume",
45+
Args: cobra.ExactArgs(2),
46+
RunE: func(cmd *cobra.Command, args []string) error {
47+
filename := args[0]
48+
contentBase64 := args[1]
49+
50+
content, err := base64.StdEncoding.DecodeString(contentBase64)
51+
if err != nil {
52+
return err
53+
}
54+
55+
return post(ctx, httpClient(), "/volume-file-content", FileContent{
56+
VolumeId: "docker-prompts",
57+
TargetPath: filename,
58+
Contents: string(content),
59+
})
60+
},
61+
}
62+
}
63+
64+
func httpClient() *http.Client {
65+
return &http.Client{
3266
Transport: &http.Transport{
3367
DialContext: func(ctx context.Context, _, _ string) (conn net.Conn, err error) {
3468
return dialVolumeContents(ctx)
3569
},
3670
},
3771
}
38-
39-
var content struct {
40-
Contents string `json:"contents"`
41-
}
42-
if err := query(ctx, httpClient, "GET", "/volume-file-content?volumeId=docker-prompts&targetPath="+filename, &content); err != nil {
43-
return "", err
44-
}
45-
46-
return content.Contents, nil
4772
}
4873

49-
func query(ctx context.Context, httpClient *http.Client, method string, endpoint string, v any) error {
50-
req, err := http.NewRequestWithContext(ctx, method, "http://localhost"+endpoint, nil)
74+
func get(ctx context.Context, httpClient *http.Client, endpoint string, v any) error {
75+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://localhost"+endpoint, nil)
5176
if err != nil {
5277
return err
5378
}
@@ -67,5 +92,33 @@ func query(ctx context.Context, httpClient *http.Client, method string, endpoint
6792
if err := json.Unmarshal(buf, &v); err != nil {
6893
return err
6994
}
95+
96+
return nil
97+
}
98+
99+
func post(ctx context.Context, httpClient *http.Client, endpoint string, v any) error {
100+
payload, err := json.Marshal(v)
101+
if err != nil {
102+
return err
103+
}
104+
105+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "http://localhost"+endpoint, bytes.NewReader(payload))
106+
if err != nil {
107+
return err
108+
}
109+
req.Header.Set("X-DockerDesktop-Host", "vm.docker.internal")
110+
req.Header.Set("Content-Type", "application/json")
111+
112+
response, err := httpClient.Do(req)
113+
if err != nil {
114+
return err
115+
}
116+
defer response.Body.Close()
117+
118+
_, err = io.ReadAll(response.Body)
119+
if err != nil {
120+
return err
121+
}
122+
70123
return nil
71124
}

src/extension/host-binary/cmd/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func main() {
2929
cmd.AddCommand(DeriveSecret(ctx))
3030
cmd.AddCommand(commands.CurrentUser(ctx))
3131
cmd.AddCommand(commands.ReadFromVolume(ctx))
32+
cmd.AddCommand(commands.WriteToVolume(ctx))
3233
if err := cmd.Execute(); err != nil {
3334
fmt.Println(err)
3435
os.Exit(1)

src/extension/ui/src/utils/Files.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,16 @@ export const writeToPromptsVolume = async (
7070
filename: string,
7171
content: string
7272
) => {
73-
return tryRunImageSync(client, [
74-
"--rm",
75-
"-v",
76-
"docker-prompts:/workdir",
77-
"--network=none",
78-
"-w",
79-
"/workdir",
80-
BUSYBOX,
81-
"/bin/sh",
82-
"-c",
83-
client.host.platform === "win32"
84-
? `\"echo ${encode(content)} | base64 -d > ${filename}\"`
85-
: `'echo ${encode(content)} | base64 -d > ${filename}'`,
86-
]);
73+
try {
74+
await client.extension.host?.cli.exec("host-binary", ["write-to-volume", filename, encode(content)]);
75+
} catch (e) {
76+
if (e instanceof Error) {
77+
client.desktopUI.toast.error(e.message);
78+
}
79+
if ((e as ExecResult).stderr) {
80+
client.desktopUI.toast.error(JSON.stringify(e));
81+
}
82+
}
8783
};
8884

8985
export const writeToMount = async (

0 commit comments

Comments
 (0)