Skip to content

Commit dfecd3e

Browse files
authored
Merge pull request #3750 from AkihiroSuda/dev-1.2
[release/1.2] cherry-picks
2 parents 4192b7c + 1279fa7 commit dfecd3e

File tree

6 files changed

+110
-37
lines changed

6 files changed

+110
-37
lines changed

cmd/limactl/start.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ func chooseNextCreatorState(ctx context.Context, tmpl *limatmpl.Template, yq str
329329
hdr += editutil.GenerateEditorWarningHeader()
330330
var err error
331331
tmpl.Bytes, err = editutil.OpenEditor(tmpl.Bytes, hdr)
332+
tmpl.Config = nil
332333
if err != nil {
333334
return tmpl, err
334335
}
@@ -337,6 +338,10 @@ func chooseNextCreatorState(ctx context.Context, tmpl *limatmpl.Template, yq str
337338
logrus.Info(msg)
338339
return nil, exitSuccessError{Msg: msg}
339340
}
341+
err = tmpl.Embed(ctx, true, true)
342+
if err != nil {
343+
return nil, err
344+
}
340345
return tmpl, nil
341346
case 2: // "Choose another template..."
342347
templates, err := filterHiddenTemplates()

pkg/instance/start.go

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ import (
1212
"os"
1313
"os/exec"
1414
"path/filepath"
15-
"syscall"
1615
"text/template"
1716
"time"
1817

1918
"github.com/docker/go-units"
2019
"github.com/lima-vm/go-qcow2reader"
21-
"github.com/mattn/go-isatty"
2220
"github.com/sirupsen/logrus"
2321

2422
"github.com/lima-vm/lima/pkg/downloader"
@@ -29,7 +27,6 @@ import (
2927
hostagentevents "github.com/lima-vm/lima/pkg/hostagent/events"
3028
"github.com/lima-vm/lima/pkg/imgutil/proxyimgutil"
3129
"github.com/lima-vm/lima/pkg/limayaml"
32-
"github.com/lima-vm/lima/pkg/osutil"
3330
"github.com/lima-vm/lima/pkg/store"
3431
"github.com/lima-vm/lima/pkg/store/filenames"
3532
"github.com/lima-vm/lima/pkg/usrlocalsharelima"
@@ -249,25 +246,7 @@ func Start(ctx context.Context, inst *store.Instance, limactl string, launchHost
249246
begin := time.Now() // used for logrus propagation
250247

251248
if launchHostAgentForeground {
252-
logrus.Info("Running the host agent in the foreground")
253-
if isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) {
254-
// Write message to standard log files to avoid confusing users
255-
message := "This log file is not used because `limactl start` was launched in the terminal with the `--foreground` option."
256-
if _, err := haStdoutW.WriteString(message); err != nil {
257-
return err
258-
}
259-
if _, err := haStderrW.WriteString(message); err != nil {
260-
return err
261-
}
262-
} else {
263-
if err := osutil.Dup2(int(haStdoutW.Fd()), syscall.Stdout); err != nil {
264-
return err
265-
}
266-
if err := osutil.Dup2(int(haStderrW.Fd()), syscall.Stderr); err != nil {
267-
return err
268-
}
269-
}
270-
if err := syscall.Exec(limactl, haCmd.Args, haCmd.Environ()); err != nil {
249+
if err := execHostAgentForeground(limactl, haCmd); err != nil {
271250
return err
272251
}
273252
} else if err := haCmd.Start(); err != nil {

pkg/instance/start_unix.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//go:build !windows
2+
3+
// SPDX-FileCopyrightText: Copyright The Lima Authors
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package instance
7+
8+
import (
9+
"fmt"
10+
"os"
11+
"os/exec"
12+
"syscall"
13+
14+
"github.com/mattn/go-isatty"
15+
"github.com/sirupsen/logrus"
16+
17+
"github.com/lima-vm/lima/pkg/osutil"
18+
)
19+
20+
func execHostAgentForeground(limactl string, haCmd *exec.Cmd) error {
21+
haStdoutW, ok := haCmd.Stdout.(*os.File)
22+
if !ok {
23+
return fmt.Errorf("expected haCmd.Stdout to be *os.File, got %T", haCmd.Stdout)
24+
}
25+
haStderrW, ok := haCmd.Stderr.(*os.File)
26+
if !ok {
27+
return fmt.Errorf("expected haCmd.Stderr to be *os.File, got %T", haCmd.Stderr)
28+
}
29+
logrus.Info("Running the host agent in the foreground")
30+
if isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) {
31+
// Write message to standard log files to avoid confusing users
32+
message := "This log file is not used because `limactl start` was launched in the terminal with the `--foreground` option."
33+
if _, err := haStdoutW.WriteString(message); err != nil {
34+
return err
35+
}
36+
if _, err := haStderrW.WriteString(message); err != nil {
37+
return err
38+
}
39+
} else {
40+
if err := osutil.Dup2(int(haStdoutW.Fd()), syscall.Stdout); err != nil {
41+
return err
42+
}
43+
if err := osutil.Dup2(int(haStderrW.Fd()), syscall.Stderr); err != nil {
44+
return err
45+
}
46+
}
47+
return syscall.Exec(limactl, haCmd.Args, haCmd.Environ())
48+
}

pkg/instance/start_windows.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-FileCopyrightText: Copyright The Lima Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package instance
5+
6+
import (
7+
"errors"
8+
"os/exec"
9+
)
10+
11+
func execHostAgentForeground(_ string, _ *exec.Cmd) error {
12+
return errors.New("`limactl start --foreground` is not supported on Windows")
13+
}

pkg/portfwd/client.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"fmt"
99
"net"
10+
"sync/atomic"
1011
"time"
1112

1213
"github.com/containers/gvisor-tap-vsock/pkg/services/forwarder"
@@ -40,33 +41,35 @@ func HandleTCPConnection(ctx context.Context, client *guestagentclient.GuestAgen
4041
}
4142

4243
func HandleUDPConnection(ctx context.Context, client *guestagentclient.GuestAgentClient, conn net.PacketConn, guestAddr string) {
43-
id := fmt.Sprintf("udp-%s", conn.LocalAddr().String())
44-
45-
stream, err := client.Tunnel(ctx)
46-
if err != nil {
47-
logrus.Errorf("could not open udp tunnel for id: %s error:%v", id, err)
48-
return
49-
}
50-
51-
// Handshake message to start tunnel
52-
if err := stream.Send(&api.TunnelMessage{Id: id, Protocol: "udp", GuestAddr: guestAddr}); err != nil {
53-
logrus.Errorf("could not start udp tunnel for id: %s error:%v", id, err)
54-
return
55-
}
44+
var udpConnectionCounter atomic.Uint32
45+
initialID := fmt.Sprintf("udp-%s", conn.LocalAddr().String())
5646

47+
// gvisor-tap-vsock's UDPProxy demultiplexes client connections internally based on their source address.
48+
// It calls this dialer function only when it receives a datagram from a new, unrecognized client.
49+
// For each new client, we must return a new net.Conn, which in our case is a new gRPC stream.
50+
// The atomic counter ensures that each stream has a unique ID to distinguish them on the server side.
5751
proxy, err := forwarder.NewUDPProxy(conn, func() (net.Conn, error) {
52+
id := fmt.Sprintf("%s-%d", initialID, udpConnectionCounter.Add(1))
53+
stream, err := client.Tunnel(ctx)
54+
if err != nil {
55+
return nil, fmt.Errorf("could not open udp tunnel for id: %s error:%w", id, err)
56+
}
57+
// Handshake message to start tunnel
58+
if err := stream.Send(&api.TunnelMessage{Id: id, Protocol: "udp", GuestAddr: guestAddr}); err != nil {
59+
return nil, fmt.Errorf("could not start udp tunnel for id: %s error:%w", id, err)
60+
}
5861
rw := &GrpcClientRW{stream: stream, id: id, addr: guestAddr, protocol: "udp"}
5962
return rw, nil
6063
})
6164
if err != nil {
62-
logrus.Errorf("error in udp tunnel proxy for id: %s error:%v", id, err)
65+
logrus.Errorf("error in udp tunnel proxy for id: %s error:%v", initialID, err)
6366
return
6467
}
6568

6669
defer func() {
6770
err := proxy.Close()
6871
if err != nil {
69-
logrus.Errorf("error in closing udp tunnel proxy for id: %s error:%v", id, err)
72+
logrus.Errorf("error in closing udp tunnel proxy for id: %s error:%v", initialID, err)
7073
}
7174
}()
7275
proxy.Run()

pkg/qemuimgutil/qemuimgutil.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,31 @@ type InfoFormatSpecificDataVmdkExtent struct {
103103
}
104104

105105
func convertToRaw(source, dest string) error {
106+
if source != dest {
107+
return execQemuImgConvert(source, dest)
108+
}
109+
110+
// If source == dest, we need to use a temporary file to avoid file locking issues
111+
112+
info, err := getInfo(source)
113+
if err != nil {
114+
return fmt.Errorf("failed to get info for source disk %q: %w", source, err)
115+
}
116+
if info.Format == "raw" {
117+
return nil
118+
}
119+
120+
tempFile := dest + ".lima-qemu-convert.tmp"
121+
defer os.Remove(tempFile)
122+
123+
if err := execQemuImgConvert(source, tempFile); err != nil {
124+
return err
125+
}
126+
127+
return os.Rename(tempFile, dest)
128+
}
129+
130+
func execQemuImgConvert(source, dest string) error {
106131
var stdout, stderr bytes.Buffer
107132
cmd := exec.Command("qemu-img", "convert", "-O", "raw", source, dest)
108133
cmd.Stdout = &stdout

0 commit comments

Comments
 (0)