(ctx context.Context)
| 695 | } |
| 696 | |
| 697 | func (a *HostAgent) watchGuestAgentEvents(ctx context.Context) { |
| 698 | // TODO: use vSock (when QEMU for macOS gets support for vSock) |
| 699 | |
| 700 | // Setup all socket forwards and defer their teardown |
| 701 | if !(a.driver.Info(ctx).Features.SkipSocketForwarding) { |
| 702 | logrus.Debugf("Forwarding unix sockets") |
| 703 | sshAddress, sshPort := a.sshAddressPort() |
| 704 | for _, rule := range a.instConfig.PortForwards { |
| 705 | if rule.GuestSocket != "" { |
| 706 | local := hostAddress(rule, &guestagentapi.IPPort{}) |
| 707 | _ = forwardSSH(ctx, a.sshConfig, sshAddress, sshPort, local, rule.GuestSocket, verbForward, rule.Reverse) |
| 708 | } |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | localUnix := filepath.Join(a.instDir, filenames.GuestAgentSock) |
| 713 | remoteUnix := "/run/lima-guestagent.sock" |
| 714 | |
| 715 | a.cleanUp(func() error { |
| 716 | logrus.Debugf("Stop forwarding unix sockets") |
| 717 | var errs []error |
| 718 | sshAddress, sshPort := a.sshAddressPort() |
| 719 | for _, rule := range a.instConfig.PortForwards { |
| 720 | if rule.GuestSocket != "" { |
| 721 | local := hostAddress(rule, &guestagentapi.IPPort{}) |
| 722 | if err := forwardSSH(ctx, a.sshConfig, sshAddress, sshPort, local, rule.GuestSocket, verbCancel, rule.Reverse); err != nil { |
| 723 | errs = append(errs, err) |
| 724 | } |
| 725 | } |
| 726 | } |
| 727 | if a.driver.ForwardGuestAgent(ctx) { |
| 728 | if err := a.cancelGuestAgentSockForward(ctx, localUnix, remoteUnix); err != nil { |
| 729 | errs = append(errs, err) |
| 730 | } |
| 731 | } |
| 732 | return errors.Join(errs...) |
| 733 | }) |
| 734 | |
| 735 | go func() { |
| 736 | if a.instConfig.MountInotify == nil || !*a.instConfig.MountInotify { |
| 737 | return |
| 738 | } |
| 739 | client := a.getClient() |
| 740 | if client == nil || !isGuestAgentSocketAccessible(ctx, client) { |
| 741 | if a.driver.ForwardGuestAgent(ctx) { |
| 742 | a.forwardGuestAgentSock(ctx, localUnix, remoteUnix) |
| 743 | } |
| 744 | } |
| 745 | // Re-spawn startInotify when its gRPC stream dies (typically because |
| 746 | // the guest agent restarted). Without this, host-side file changes |
| 747 | // silently stop propagating into the guest after the first reconnect. |
| 748 | for { |
| 749 | if err := a.startInotify(ctx); err != nil && !errors.Is(err, context.Canceled) { |
| 750 | logrus.WithError(err).Warn("inotify stream ended; will retry") |
| 751 | } |
| 752 | select { |
| 753 | case <-ctx.Done(): |
| 754 | return |
no test coverage detected