• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubevirt / kubevirt / 8bfd7554-c52b-4041-b9b8-e02fc051489d

24 Feb 2026 02:51AM UTC coverage: 71.17% (+0.001%) from 71.169%
8bfd7554-c52b-4041-b9b8-e02fc051489d

push

prow

web-flow
Merge pull request #16880 from 0xFelix/fix-deprecated-apis-alert

fix(monitoring): Do not fire KubeVirtDeprecatedAPIRequested for DELETE

4 of 4 new or added lines in 1 file covered. (100.0%)

36 existing lines in 2 files now uncovered.

74033 of 104023 relevant lines covered (71.17%)

591.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.42
/pkg/virt-handler/notify-server/pipe/pipe.go
1
/*
2
 * This file is part of the KubeVirt project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 *
16
 * Copyright The KubeVirt Authors.
17
 *
18
 */
19

20
// Package pipe provides utilities for proxying domain notify connections
21
// between virt-launcher pods and virt-handler's notify server.
22
//
23
// The pipe acts as a bridge, creating a unix socket within the VMI's
24
// filesystem that proxies to virt-handler's domain-notify.sock.
25
package pipe
26

27
import (
28
        "context"
29
        "errors"
30
        "fmt"
31
        "io"
32
        "net"
33
        "path/filepath"
34
        "time"
35

36
        "kubevirt.io/client-go/log"
37

38
        diskutils "kubevirt.io/kubevirt/pkg/ephemeral-disk-utils"
39
        "kubevirt.io/kubevirt/pkg/safepath"
40
        "kubevirt.io/kubevirt/pkg/virt-handler/isolation"
41
)
42

43
func NewConnectToNotifyFunc(virtShareDir string) connectFunc {
15✔
44
        return func() (net.Conn, error) {
30✔
45
                conn, err := net.Dial("unix", filepath.Join(virtShareDir, "domain-notify.sock"))
15✔
46
                if err != nil {
24✔
47
                        return nil, fmt.Errorf("error connecting to domain-notify.sock: %w", err)
9✔
48
                }
9✔
49
                return conn, err
6✔
50
        }
51
}
52

53
// InjectNotify injects the domain-notify.sock into the VMI pod and listens for connections
54
func InjectNotify(pod isolation.IsolationResult, virtShareDir string,
55
        nonRoot bool) (net.Listener, error) {
3✔
56
        root, err := pod.MountRoot()
3✔
57
        if err != nil {
3✔
58
                return nil, err
×
59
        }
×
60
        socketDir, err := root.AppendAndResolveWithRelativeRoot(virtShareDir)
3✔
61
        if err != nil {
3✔
62
                return nil, err
×
63
        }
×
64

65
        listener, err := safepath.ListenUnixNoFollow(socketDir, "domain-notify-pipe.sock")
3✔
66
        if err != nil {
3✔
67
                return nil, fmt.Errorf("failed to create unix socket for proxy service: %w", err)
×
68
        }
×
69

70
        if nonRoot {
4✔
71
                socketPath, err := safepath.JoinNoFollow(socketDir, "domain-notify-pipe.sock")
1✔
72
                if err != nil {
1✔
73
                        return nil, err
×
74
                }
×
75

76
                err = diskutils.DefaultOwnershipManager.SetFileOwnership(socketPath)
1✔
77
                if err != nil {
1✔
78
                        return nil, fmt.Errorf("unable to change ownership for domain notify: %w", err)
×
79
                }
×
80
        }
81

82
        return listener, nil
3✔
83
}
84

85
type connectFunc func() (net.Conn, error)
86
type proxyFunc func(net.Conn)
87

88
func Pipe(ctx context.Context, pipeChan chan net.Conn, proxy proxyFunc) {
6✔
89
        for {
28✔
90
                select {
22✔
91
                case <-ctx.Done():
5✔
92
                        return
5✔
93
                case fd, open := <-pipeChan:
17✔
94
                        if !open {
18✔
95
                                return
1✔
96
                        }
1✔
97
                        go proxy(fd)
16✔
98
                }
99
        }
100
}
101

102
// Proxy is blocking, it proxies pipe connection [pipeConn] to given connection [connect](ultimately to notify server)
103
// pipeConn is closed on success or error
104
func Proxy(logger *log.FilteredLogger, pipeConn net.Conn, connect connectFunc) {
16✔
105
        defer pipeConn.Close()
16✔
106

16✔
107
        // proxy the VMI domain-notify-pipe.sock to the virt-handler domain-notify.sock
16✔
108
        // so virt-handler receives notifications from the VMI
16✔
109
        notifyConn, err := connect()
16✔
110
        if err != nil {
25✔
111
                logger.Reason(err).Error("error connecting for proxy connection")
9✔
112
                return
9✔
113
        }
9✔
114
        defer notifyConn.Close()
7✔
115

7✔
116
        logger.Infof("Accepted new notify pipe connection")
7✔
117
        copyErr := make(chan error, 2)
7✔
118
        go func() {
14✔
119
                _, err := io.Copy(pipeConn, notifyConn)
7✔
120
                copyErr <- err
7✔
121
        }()
7✔
122
        go func() {
14✔
123
                _, err := io.Copy(notifyConn, pipeConn)
7✔
124
                copyErr <- err
7✔
125
        }()
7✔
126

127
        // wait until one of the copy routines exit then
128
        // let the connections close
129
        if err = <-copyErr; err != nil {
7✔
UNCOV
130
                logger.Reason(err).Infof("closing notify pipe connection")
×
131
        } else {
7✔
132
                logger.Infof("gracefully closed notify pipe connection")
7✔
133
        }
7✔
134
}
135

136
func ChanFromListener(ctx context.Context, logger *log.FilteredLogger, listener net.Listener) chan net.Conn {
4✔
137
        connectionChan := make(chan net.Conn, 100)
4✔
138
        // Close listener and exit when stop encountered
4✔
139
        go func() {
8✔
140
                <-ctx.Done()
4✔
141
                logger.Infof("closing notify pipe listener for vmi")
4✔
142
                if err := listener.Close(); err != nil {
4✔
143
                        logger.Infof("failed closing notify pipe listener for vmi: %v", err)
×
144
                }
×
145
        }()
146

147
        // Listen for new connections,
148
        go func() {
8✔
149
                for {
24✔
150
                        conn, err := listener.Accept()
20✔
151
                        if err != nil {
24✔
152
                                if errors.Is(err, net.ErrClosed) {
8✔
153
                                        // As Accept blocks, closing it is our mechanism to exit this loop
4✔
154
                                        return
4✔
155
                                }
4✔
156
                                logger.Reason(err).Error("Domain pipe accept error encountered.")
×
157
                                // keep listening until stop invoked
×
158
                                time.Sleep(1 * time.Second)
×
159
                        } else {
16✔
160
                                connectionChan <- conn
16✔
161
                        }
16✔
162
                }
163
        }()
164
        return connectionChan
4✔
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc