@@ -11,6 +11,7 @@ import (
1111 "errors"
1212 "fmt"
1313 "io"
14+ "maps"
1415 "net"
1516 "os"
1617 "os/exec"
@@ -113,6 +114,82 @@ func WithCloudInitProgress(enabled bool) Opt {
113114 }
114115}
115116
117+ // resolvePortForwardTypes resolves port forwarding types.
118+ // The returned result may not contain [limatype.ProtoAny] keys, and [limatype.PortForwardTypeNone] values.
119+ func resolvePortForwardTypes (portForwardTypes map [limatype.Proto ]limatype.PortForwardType , portForwards []limatype.PortForward ) (map [limatype.Proto ]limatype.PortForwardType , error ) {
120+ // The default port forwarding mode since Lima v2.0 is "dual": {tcp: ssh, udp: grpc}.
121+ // The default values are set in [limayaml.FillDefault], not here.
122+ if err := limayaml .ValidatePortForwardTypes (portForwardTypes ); err != nil {
123+ return nil , err
124+ }
125+
126+ res := maps .Clone (portForwardTypes )
127+
128+ // Fix up keys
129+ for k , v := range res {
130+ if k == limatype .ProtoAny {
131+ for _ , proto := range []limatype.Proto {limatype .ProtoTCP , limatype .ProtoUDP } {
132+ if res [proto ] != limatype .PortForwardTypeNone {
133+ res [proto ] = v
134+ }
135+ }
136+ delete (res , k )
137+ }
138+ }
139+
140+ // Fix up values
141+ for k , v := range res {
142+ if v == limatype .PortForwardTypeNone {
143+ delete (res , k )
144+ }
145+ }
146+
147+ // Apply "ignore all ports" rules from portForwards
148+ for _ , rule := range portForwards {
149+ if rule .Ignore && rule .GuestPortRange [0 ] == 1 && rule .GuestPortRange [1 ] == 65535 {
150+ switch rule .Proto {
151+ case limatype .ProtoTCP :
152+ delete (res , limatype .ProtoTCP )
153+ case limatype .ProtoUDP :
154+ delete (res , limatype .ProtoUDP )
155+ case limatype .ProtoAny :
156+ delete (res , limatype .ProtoTCP )
157+ delete (res , limatype .ProtoUDP )
158+ }
159+ } else {
160+ break
161+ }
162+ }
163+
164+ // Apply LIMA_SSH_PORT_FORWARDER env var for backward compatibility
165+ if envVar := os .Getenv ("LIMA_SSH_PORT_FORWARDER" ); envVar != "" {
166+ logrus .WithField ("LIMA_SSH_PORT_FORWARDER" , envVar ).Warnf ("LIMA_SSH_PORT_FORWARDER=false is deprecated; use portForwardTypes config instead" )
167+ b , err := strconv .ParseBool (envVar )
168+ if err != nil {
169+ return nil , fmt .Errorf ("invalid LIMA_SSH_PORT_FORWARDER value %q" , envVar )
170+ }
171+ if b {
172+ if _ , ok := res [limatype .ProtoTCP ]; ok {
173+ res [limatype .ProtoTCP ] = limatype .PortForwardTypeSSH
174+ }
175+ // No UDP support in SSH port forwarder
176+ delete (res , limatype .ProtoUDP )
177+ } else {
178+ for _ , proto := range []limatype.Proto {limatype .ProtoTCP , limatype .ProtoUDP } {
179+ if _ , ok := res [proto ]; ok {
180+ res [proto ] = limatype .PortForwardTypeGRPC
181+ }
182+ }
183+ }
184+ }
185+
186+ if err := limayaml .ValidatePortForwardTypes (res ); err != nil {
187+ return nil , err
188+ }
189+
190+ return res , nil
191+ }
192+
116193// New creates the HostAgent.
117194//
118195// stdout is for emitting JSON lines of Events.
@@ -202,26 +279,15 @@ func New(ctx context.Context, instName string, stdout io.Writer, signalCh chan o
202279 AdditionalArgs : sshutil .SSHArgsFromOpts (sshOpts ),
203280 }
204281
205- ignoreTCP := false
206- ignoreUDP := false
207- for _ , rule := range inst .Config .PortForwards {
208- if rule .Ignore && rule .GuestPortRange [0 ] == 1 && rule .GuestPortRange [1 ] == 65535 {
209- switch rule .Proto {
210- case limatype .ProtoTCP :
211- ignoreTCP = true
212- logrus .Info ("TCP port forwarding is disabled (except for SSH)" )
213- case limatype .ProtoUDP :
214- ignoreUDP = true
215- logrus .Info ("UDP port forwarding is disabled" )
216- case limatype .ProtoAny :
217- ignoreTCP = true
218- ignoreUDP = true
219- logrus .Info ("TCP (except for SSH) and UDP port forwarding is disabled" )
220- }
221- } else {
222- break
223- }
282+ portForwardTypes , err := resolvePortForwardTypes (inst .Config .PortForwardTypes , inst .Config .PortForwards )
283+ if err != nil {
284+ return nil , err
224285 }
286+ logrus .WithField ("portForwardTypes" , portForwardTypes ).Info ("Resolved port forwarding types" )
287+ sshFwdIgnoreTCP := portForwardTypes [limatype .ProtoTCP ] != limatype .PortForwardTypeSSH
288+ grpcFwdIgnoreTCP := portForwardTypes [limatype .ProtoTCP ] != limatype .PortForwardTypeGRPC
289+ grpcFwdIgnoreUDP := portForwardTypes [limatype .ProtoUDP ] != limatype .PortForwardTypeGRPC
290+
225291 rules := make ([]limatype.PortForward , 0 , 3 + len (inst .Config .PortForwards ))
226292 // Block ports 22 and sshLocalPort on all IPs
227293 for _ , port := range []int {sshGuestPort , sshLocalPort } {
@@ -244,8 +310,8 @@ func New(ctx context.Context, instName string, stdout io.Writer, signalCh chan o
244310 instName : instName ,
245311 instSSHAddress : inst .SSHAddress ,
246312 sshConfig : sshConfig ,
247- portForwarder : newPortForwarder (sshConfig , sshLocalPort , rules , ignoreTCP , inst .VMType ),
248- grpcPortForwarder : portfwd .NewPortForwarder (rules , ignoreTCP , ignoreUDP ),
313+ portForwarder : newPortForwarder (sshConfig , sshLocalPort , rules , sshFwdIgnoreTCP , inst .VMType ),
314+ grpcPortForwarder : portfwd .NewPortForwarder (rules , grpcFwdIgnoreTCP , grpcFwdIgnoreUDP ),
249315 driver : limaDriver ,
250316 signalCh : signalCh ,
251317 eventEnc : json .NewEncoder (stdout ),
@@ -796,26 +862,10 @@ func (a *HostAgent) processGuestAgentEvents(ctx context.Context, client *guestag
796862 for _ , f := range ev .Errors {
797863 logrus .Warnf ("received error from the guest: %q" , f )
798864 }
799- // History of the default value of useSSHFwd:
800- // - v0.1.0: true (effectively)
801- // - v1.0.0: false
802- // - v1.0.1: true
803- // - v1.1.0-beta.0: false
804- useSSHFwd := false
805- if envVar := os .Getenv ("LIMA_SSH_PORT_FORWARDER" ); envVar != "" {
806- b , err := strconv .ParseBool (envVar )
807- if err != nil {
808- logrus .WithError (err ).Warnf ("invalid LIMA_SSH_PORT_FORWARDER value %q" , envVar )
809- } else {
810- useSSHFwd = b
811- }
812- }
813- if useSSHFwd {
814- a .portForwarder .OnEvent (ctx , ev )
815- } else {
816- dialContext := portfwd .DialContextToGRPCTunnel (client )
817- a .grpcPortForwarder .OnEvent (ctx , dialContext , ev )
818- }
865+
866+ a .portForwarder .OnEvent (ctx , ev )
867+ dialContext := portfwd .DialContextToGRPCTunnel (client )
868+ a .grpcPortForwarder .OnEvent (ctx , dialContext , ev )
819869 }
820870
821871 if err := client .Events (ctx , onEvent ); err != nil {
0 commit comments