mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	node: re-implement Localendpoint on windows
this will allows us to move forward with the podresources endpoint GA graduation. xref: https://github.com/kubernetes/kubernetes/issues/78628 Signed-off-by: Francesco Romani <fromani@redhat.com>
This commit is contained in:
		@@ -230,6 +230,7 @@ func ListenAndServePodResources(endpoint string, providers podresources.PodResou
 | 
				
			|||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						klog.InfoS("Starting to serve the podresources API", "endpoint", endpoint)
 | 
				
			||||||
	if err := server.Serve(l); err != nil {
 | 
						if err := server.Serve(l); err != nil {
 | 
				
			||||||
		klog.ErrorS(err, "Failed to serve")
 | 
							klog.ErrorS(err, "Failed to serve")
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@@ -117,9 +118,27 @@ func parseEndpoint(endpoint string) (string, string, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LocalEndpoint empty implementation
 | 
					// LocalEndpoint returns the full path to a named pipe at the given endpoint - unlike on unix, we can't use sockets.
 | 
				
			||||||
func LocalEndpoint(path, file string) (string, error) {
 | 
					func LocalEndpoint(path, file string) (string, error) {
 | 
				
			||||||
	return "", fmt.Errorf("LocalEndpoints are unsupported in this build")
 | 
						// extract the podresources config name from the path. We only need this on windows because the preferred layout of pipes,
 | 
				
			||||||
 | 
						// this is why we have the extra logic in here instead of changing the function signature. Join the file to make sure the
 | 
				
			||||||
 | 
						// last path component is a file, so the operation chain works..
 | 
				
			||||||
 | 
						podResourcesDir := filepath.Base(filepath.Dir(filepath.Join(path, file)))
 | 
				
			||||||
 | 
						if podResourcesDir == "" {
 | 
				
			||||||
 | 
							// should not happen because the user can configure a root directory, and we expected a subdirectory inside
 | 
				
			||||||
 | 
							// the user supplied root directory named like "pod-resources" or so.
 | 
				
			||||||
 | 
							return "", fmt.Errorf("cannot infer the podresources directory from path %q", path)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// windows pipes are expected to use forward slashes: https://learn.microsoft.com/windows/win32/ipc/pipe-names
 | 
				
			||||||
 | 
						// so using `url` like we do on unix gives us unclear benefits - see https://github.com/kubernetes/kubernetes/issues/78628
 | 
				
			||||||
 | 
						// So we just construct the path from scratch.
 | 
				
			||||||
 | 
						// Format: \\ServerName\pipe\PipeName
 | 
				
			||||||
 | 
						// Where where ServerName is either the name of a remote computer or a period, to specify the local computer.
 | 
				
			||||||
 | 
						// We only consider PipeName as regular windows path, while the pipe path components are fixed, hence we use constants.
 | 
				
			||||||
 | 
						serverPart := `\\.`
 | 
				
			||||||
 | 
						pipePart := "pipe"
 | 
				
			||||||
 | 
						pipeName := "kubelet-" + podResourcesDir
 | 
				
			||||||
 | 
						return npipeProtocol + "://" + filepath.Join(serverPart, pipePart, pipeName), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var tickCount = syscall.NewLazyDLL("kernel32.dll").NewProc("GetTickCount64")
 | 
					var tickCount = syscall.NewLazyDLL("kernel32.dll").NewProc("GetTickCount64")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -277,3 +277,48 @@ func TestNormalizePath(t *testing.T) {
 | 
				
			|||||||
		assert.Equal(t, test.normalizedPath, NormalizePath(test.originalpath))
 | 
							assert.Equal(t, test.normalizedPath, NormalizePath(test.originalpath))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestLocalEndpoint(t *testing.T) {
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							path             string
 | 
				
			||||||
 | 
							file             string
 | 
				
			||||||
 | 
							expectError      bool
 | 
				
			||||||
 | 
							expectedFullPath string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								path:             "/var/lib/kubelet/pod-resources",
 | 
				
			||||||
 | 
								file:             "kube.sock", // this is not the default, but it's not relevant here
 | 
				
			||||||
 | 
								expectError:      false,
 | 
				
			||||||
 | 
								expectedFullPath: `npipe://\\.\pipe\kubelet-pod-resources`,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, test := range tests {
 | 
				
			||||||
 | 
							fullPath, err := LocalEndpoint(test.path, test.file)
 | 
				
			||||||
 | 
							if test.expectError {
 | 
				
			||||||
 | 
								assert.NotNil(t, err, "expected error")
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							assert.Nil(t, err, "expected no error")
 | 
				
			||||||
 | 
							assert.Equal(t, test.expectedFullPath, fullPath)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestLocalEndpointRoundTrip(t *testing.T) {
 | 
				
			||||||
 | 
						npipeDialPointer := reflect.ValueOf(npipeDial).Pointer()
 | 
				
			||||||
 | 
						expectedDialerName := runtime.FuncForPC(npipeDialPointer).Name()
 | 
				
			||||||
 | 
						expectedAddress := "//./pipe/kubelet-pod-resources"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fullPath, err := LocalEndpoint(`pod-resources`, "kubelet")
 | 
				
			||||||
 | 
						require.NoErrorf(t, err, "Failed to create the local endpoint path")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						address, dialer, err := GetAddressAndDialer(fullPath)
 | 
				
			||||||
 | 
						require.NoErrorf(t, err, "Failed to parse the endpoint path and get back address and dialer (path=%q)", fullPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dialerPointer := reflect.ValueOf(dialer).Pointer()
 | 
				
			||||||
 | 
						actualDialerName := runtime.FuncForPC(dialerPointer).Name()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.Equalf(t, npipeDialPointer, dialerPointer,
 | 
				
			||||||
 | 
							"Expected dialer %s, but get %s", expectedDialerName, actualDialerName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.Equal(t, expectedAddress, address)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user