github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/helper/containercenter/mount_windows.go (about) 1 // Copyright 2021 iLogtail Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package containercenter 16 17 import ( 18 "flag" 19 "fmt" 20 "io/fs" 21 "os" 22 "strings" 23 24 "github.com/alibaba/ilogtail/pkg/util" 25 ) 26 27 // Used to collect text files in containers. 28 // Users need to mount the path expected to collect to driver C, so that 29 // Logtail container can access them from this path. 30 // For example, user container mounts host path C:\logs\ to container 31 // path C:\app\logs\, then Logtail can access this directory through 32 // C:\logtail_host\logs\. Therefore, user can set Logtail to collect 33 // text files under C:\app\logs\, such as C:\app\logs\nginx\. 34 // Type of mount: 35 // - Docker: -v option when run container. 36 // - Kubernetes: emptyDir volumn. 37 var DefaultLogtailMountPath string 38 39 const dockerInstallPathFlagName = "WINDOWS_DOCKER_INSTALL_PATH" 40 const dockerDataMountPathFlagName = "WINDOWS_DOCKER_DATA_MOUNT_PATH" 41 42 // DockerInstallPath and DockerDataMountPath are used for Windows that 43 // has multiple drivers. For such case, docker data can be saved on 44 // non-C driver (DockerInstallPath) and be mounted to driver C (DockerDataMountPath). 45 // 46 // Example: 47 // DockerInstallPath is E:\docker\, DockerDataMountPath is C:\ProgramData\docker\, 48 // user file path from docker engine is E:\docker\containers\<id>\<id>.json, 49 // Logtail can access it from C:\ProgramData\docker\containers\<id>\<id>.json, 50 // because DockerDataMountPath will be mounted into Logtail container with 51 // same path. 52 var DockerInstallPath = flag.String(dockerInstallPathFlagName, "", "") 53 var DockerDataMountPath = flag.String(dockerDataMountPathFlagName, "C:\\ProgramData\\docker", "") 54 55 func init() { 56 util.InitFromEnvString(dockerInstallPathFlagName, DockerInstallPath, *DockerInstallPath) 57 *DockerInstallPath = addPathSeparatorAtEnd(*DockerInstallPath) 58 // Driver letter is removed from DockerInstallPath to support Kubernetes, 59 // because different Nodes can install docker to different drivers. 60 // eg. Node 1 installs docker in D:\docker\, Node 2 installs docker 61 // in E:\docker\, both of them mount docker path to C:\ProgramData\docker, 62 // so the actual driver letter is unnecessary. 63 *DockerInstallPath = removeDriverLetter(*DockerInstallPath) 64 65 util.InitFromEnvString(dockerDataMountPathFlagName, DockerDataMountPath, *DockerDataMountPath) 66 *DockerDataMountPath = addPathSeparatorAtEnd(*DockerDataMountPath) 67 68 defaultPath := "C:\\logtail_host" 69 _, err := os.Stat(defaultPath) 70 // only change default mount path when `C:\logtail_host` path exists. 71 if err == nil { 72 DefaultLogtailMountPath = defaultPath 73 } else { 74 DefaultLogtailMountPath = "C:" 75 } 76 fmt.Printf("running with mount path: %s", DefaultLogtailMountPath) 77 } 78 79 // addPathSeparatorAtEnd adds path separator at the end of file path. 80 func addPathSeparatorAtEnd(filePath string) string { 81 if filePath == "" || isPathSeparator(filePath[len(filePath)-1]) { 82 return filePath 83 } 84 return filePath + "\\" 85 } 86 87 // removeDriverLetter removes driver letter and its colon. 88 // Examples: 89 // - D:\ -> \ 90 // - E:\docker\ -> \docker\ 91 func removeDriverLetter(filePath string) string { 92 if colonPos := strings.Index(filePath, ":"); colonPos != -1 { 93 return filePath[colonPos+1:] 94 } 95 return filePath 96 } 97 98 func GetMountedFilePath(filePath string) string { 99 // No specific installed path, use driver C. 100 if *DockerInstallPath == "" { 101 return GetMountedFilePathWithBasePath(DefaultLogtailMountPath, filePath) 102 } 103 // Installed path is not under driver C, remove prefix from filePath 104 // and use mount path as base path. 105 tempFilePath := removeDriverLetter(filePath) 106 if strings.HasPrefix(tempFilePath, *DockerInstallPath) { 107 return *DockerDataMountPath + tempFilePath[len(*DockerInstallPath):] 108 } 109 return filePath 110 } 111 112 func GetMountedFilePathWithBasePath(basePath, filePath string) string { 113 if 0 == len(filePath) || 0 == len(basePath) { 114 return "" 115 } 116 colonPos := strings.Index(filePath, ":") 117 if -1 == colonPos { 118 // Case: containerd, filePath is not start with driver letter. e.g. \\var\\logs\\pods\\xxx\\0.log. 119 return filePath 120 } 121 return basePath + filePath[colonPos+1:] 122 } 123 124 func TryGetRealPath(path string) (string, fs.FileInfo) { 125 if f, err := os.Stat(path); err == nil { 126 return path, f 127 } 128 return "", nil 129 }