k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/kubelet/util/util_windows.go (about)

     1  //go:build windows
     2  // +build windows
     3  
     4  /*
     5  Copyright 2017 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package util
    21  
    22  import (
    23  	"fmt"
    24  	"path/filepath"
    25  	"strings"
    26  	"syscall"
    27  	"time"
    28  )
    29  
    30  const npipeProtocol = "npipe"
    31  
    32  // LocalEndpoint returns the full path to a named pipe at the given endpoint - unlike on unix, we can't use sockets.
    33  func LocalEndpoint(path, file string) (string, error) {
    34  	// extract the podresources config name from the path. We only need this on windows because the preferred layout of pipes,
    35  	// this is why we have the extra logic in here instead of changing the function signature. Join the file to make sure the
    36  	// last path component is a file, so the operation chain works..
    37  	podResourcesDir := filepath.Base(filepath.Dir(filepath.Join(path, file)))
    38  	if podResourcesDir == "" {
    39  		// should not happen because the user can configure a root directory, and we expected a subdirectory inside
    40  		// the user supplied root directory named like "pod-resources" or so.
    41  		return "", fmt.Errorf("cannot infer the podresources directory from path %q", path)
    42  	}
    43  	// windows pipes are expected to use forward slashes: https://learn.microsoft.com/windows/win32/ipc/pipe-names
    44  	// so using `url` like we do on unix gives us unclear benefits - see https://github.com/kubernetes/kubernetes/issues/78628
    45  	// So we just construct the path from scratch.
    46  	// Format: \\ServerName\pipe\PipeName
    47  	// Where where ServerName is either the name of a remote computer or a period, to specify the local computer.
    48  	// We only consider PipeName as regular windows path, while the pipe path components are fixed, hence we use constants.
    49  	serverPart := `\\.`
    50  	pipePart := "pipe"
    51  	pipeName := "kubelet-" + podResourcesDir
    52  	return npipeProtocol + "://" + filepath.Join(serverPart, pipePart, pipeName), nil
    53  }
    54  
    55  var tickCount = syscall.NewLazyDLL("kernel32.dll").NewProc("GetTickCount64")
    56  
    57  // GetBootTime returns the time at which the machine was started, truncated to the nearest second
    58  func GetBootTime() (time.Time, error) {
    59  	currentTime := time.Now()
    60  	output, _, err := tickCount.Call()
    61  	if errno, ok := err.(syscall.Errno); !ok || errno != 0 {
    62  		return time.Time{}, err
    63  	}
    64  	return currentTime.Add(-time.Duration(output) * time.Millisecond).Truncate(time.Second), nil
    65  }
    66  
    67  // NormalizePath converts FS paths returned by certain go frameworks (like fsnotify)
    68  // to native Windows paths that can be passed to Windows specific code
    69  func NormalizePath(path string) string {
    70  	path = strings.ReplaceAll(path, "/", "\\")
    71  	if strings.HasPrefix(path, "\\") {
    72  		path = "c:" + path
    73  	}
    74  	return path
    75  }