diff --git a/pkg/kubelet/dockertools/docker.go b/pkg/kubelet/dockertools/docker.go index 4a3f162de4e..e71f93d96b6 100644 --- a/pkg/kubelet/dockertools/docker.go +++ b/pkg/kubelet/dockertools/docker.go @@ -45,6 +45,7 @@ const ( PodInfraContainerName = leaky.PodInfraContainerName DockerPrefix = "docker://" LogSuffix = "log" + ext4MaxFileNameLen = 255 ) const ( @@ -300,7 +301,13 @@ func ParseDockerName(name string) (dockerName *KubeletContainerName, hash uint64 } func LogSymlink(containerLogsDir, podFullName, containerName, dockerId string) string { - return path.Join(containerLogsDir, fmt.Sprintf("%s_%s-%s.%s", podFullName, containerName, dockerId, LogSuffix)) + suffix := fmt.Sprintf(".%s", LogSuffix) + logPath := fmt.Sprintf("%s_%s-%s", podFullName, containerName, dockerId) + // Length of a filename cannot exceed 255 characters in ext4 on Linux. + if len(logPath) > ext4MaxFileNameLen-len(suffix) { + logPath = logPath[:ext4MaxFileNameLen-len(suffix)] + } + return path.Join(containerLogsDir, logPath+suffix) } // Get a *dockerapi.Client, either using the endpoint passed in, or using diff --git a/pkg/kubelet/dockertools/docker_test.go b/pkg/kubelet/dockertools/docker_test.go index 81c4d00bcfd..a43b1cc8872 100644 --- a/pkg/kubelet/dockertools/docker_test.go +++ b/pkg/kubelet/dockertools/docker_test.go @@ -20,6 +20,8 @@ import ( "encoding/json" "fmt" "hash/adler32" + "math/rand" + "path" "reflect" "sort" "strconv" @@ -801,3 +803,24 @@ func TestMilliCPUToQuota(t *testing.T) { } } } + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +func randStringBytes(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return string(b) +} + +func TestLogSymLink(t *testing.T) { + as := assert.New(t) + containerLogsDir := "/foo/bar" + podFullName := randStringBytes(128) + containerName := randStringBytes(70) + dockerId := randStringBytes(80) + // The file name cannot exceed 255 characters. Since .log suffix is required, the prefix cannot exceed 251 characters. + expectedPath := path.Join(containerLogsDir, fmt.Sprintf("%s_%s-%s", podFullName, containerName, dockerId)[:251]+".log") + as.Equal(expectedPath, LogSymlink(containerLogsDir, podFullName, containerName, dockerId)) +}