Skip to content

Commit 26b1d34

Browse files
authored
Merge pull request kubernetes#129893 from simonfogliato/kubelet-log-permissions
Use uncompressed kubelet log file permissions when compressed.
2 parents 648620d + 5942cd8 commit 26b1d34

File tree

2 files changed

+36
-24
lines changed

2 files changed

+36
-24
lines changed

pkg/kubelet/logs/container_log_manager.go

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func GetAllLogs(log string) ([]string, error) {
7979
pattern := fmt.Sprintf("%s.*", log)
8080
logs, err := filepath.Glob(pattern)
8181
if err != nil {
82-
return nil, fmt.Errorf("failed to list all log files with pattern %q: %v", pattern, err)
82+
return nil, fmt.Errorf("failed to list all log files with pattern %q: %w", pattern, err)
8383
}
8484
inuse, _ := filterUnusedLogs(logs)
8585
sort.Strings(inuse)
@@ -113,7 +113,7 @@ func UncompressLog(log string) (_ io.ReadCloser, retErr error) {
113113
}
114114
f, err := os.Open(log)
115115
if err != nil {
116-
return nil, fmt.Errorf("failed to open log: %v", err)
116+
return nil, fmt.Errorf("failed to open log: %w", err)
117117
}
118118
defer func() {
119119
if retErr != nil {
@@ -122,7 +122,7 @@ func UncompressLog(log string) (_ io.ReadCloser, retErr error) {
122122
}()
123123
r, err := gzip.NewReader(f)
124124
if err != nil {
125-
return nil, fmt.Errorf("failed to create gzip reader: %v", err)
125+
return nil, fmt.Errorf("failed to create gzip reader: %w", err)
126126
}
127127
return &compressReadCloser{f: f, Reader: r}, nil
128128
}
@@ -158,7 +158,7 @@ func NewContainerLogManager(runtimeService internalapi.RuntimeService, osInterfa
158158
}
159159
parsedMaxSize, err := parseMaxSize(maxSize)
160160
if err != nil {
161-
return nil, fmt.Errorf("failed to parse container log max size %q: %v", maxSize, err)
161+
return nil, fmt.Errorf("failed to parse container log max size %q: %w", maxSize, err)
162162
}
163163
// Negative number means to disable container log rotation
164164
if parsedMaxSize < 0 {
@@ -205,20 +205,20 @@ func (c *containerLogManager) Clean(ctx context.Context, containerID string) err
205205
defer c.mutex.Unlock()
206206
resp, err := c.runtimeService.ContainerStatus(ctx, containerID, false)
207207
if err != nil {
208-
return fmt.Errorf("failed to get container status %q: %v", containerID, err)
208+
return fmt.Errorf("failed to get container status %q: %w", containerID, err)
209209
}
210210
if resp.GetStatus() == nil {
211211
return fmt.Errorf("container status is nil for %q", containerID)
212212
}
213213
pattern := fmt.Sprintf("%s*", resp.GetStatus().GetLogPath())
214214
logs, err := c.osInterface.Glob(pattern)
215215
if err != nil {
216-
return fmt.Errorf("failed to list all log files with pattern %q: %v", pattern, err)
216+
return fmt.Errorf("failed to list all log files with pattern %q: %w", pattern, err)
217217
}
218218

219219
for _, l := range logs {
220220
if err := c.osInterface.Remove(l); err != nil && !os.IsNotExist(err) {
221-
return fmt.Errorf("failed to remove container %q log %q: %v", containerID, l, err)
221+
return fmt.Errorf("failed to remove container %q log %q: %w", containerID, l, err)
222222
}
223223
}
224224

@@ -239,7 +239,7 @@ func (c *containerLogManager) rotateLogs(ctx context.Context) error {
239239
// TODO(#59998): Use kubelet pod cache.
240240
containers, err := c.runtimeService.ListContainers(ctx, &runtimeapi.ContainerFilter{})
241241
if err != nil {
242-
return fmt.Errorf("failed to list containers: %v", err)
242+
return fmt.Errorf("failed to list containers: %w", err)
243243
}
244244
for _, container := range containers {
245245
// Only rotate logs for running containers. Non-running containers won't
@@ -315,17 +315,17 @@ func (c *containerLogManager) rotateLog(ctx context.Context, id, log string) err
315315
pattern := fmt.Sprintf("%s.*", log)
316316
logs, err := filepath.Glob(pattern)
317317
if err != nil {
318-
return fmt.Errorf("failed to list all log files with pattern %q: %v", pattern, err)
318+
return fmt.Errorf("failed to list all log files with pattern %q: %w", pattern, err)
319319
}
320320

321321
logs, err = c.cleanupUnusedLogs(logs)
322322
if err != nil {
323-
return fmt.Errorf("failed to cleanup logs: %v", err)
323+
return fmt.Errorf("failed to cleanup logs: %w", err)
324324
}
325325

326326
logs, err = c.removeExcessLogs(logs)
327327
if err != nil {
328-
return fmt.Errorf("failed to remove excess logs: %v", err)
328+
return fmt.Errorf("failed to remove excess logs: %w", err)
329329
}
330330

331331
// Compress uncompressed log files.
@@ -334,12 +334,12 @@ func (c *containerLogManager) rotateLog(ctx context.Context, id, log string) err
334334
continue
335335
}
336336
if err := c.compressLog(l); err != nil {
337-
return fmt.Errorf("failed to compress log %q: %v", l, err)
337+
return fmt.Errorf("failed to compress log %q: %w", l, err)
338338
}
339339
}
340340

341341
if err := c.rotateLatestLog(ctx, id, log); err != nil {
342-
return fmt.Errorf("failed to rotate log %q: %v", log, err)
342+
return fmt.Errorf("failed to rotate log %q: %w", log, err)
343343
}
344344

345345
return nil
@@ -351,7 +351,7 @@ func (c *containerLogManager) cleanupUnusedLogs(logs []string) ([]string, error)
351351
inuse, unused := filterUnusedLogs(logs)
352352
for _, l := range unused {
353353
if err := c.osInterface.Remove(l); err != nil {
354-
return nil, fmt.Errorf("failed to remove unused log %q: %v", l, err)
354+
return nil, fmt.Errorf("failed to remove unused log %q: %w", l, err)
355355
}
356356
}
357357
return inuse, nil
@@ -404,7 +404,7 @@ func (c *containerLogManager) removeExcessLogs(logs []string) ([]string, error)
404404
i := 0
405405
for ; i < len(logs)-maxRotatedFiles; i++ {
406406
if err := c.osInterface.Remove(logs[i]); err != nil {
407-
return nil, fmt.Errorf("failed to remove old log %q: %v", logs[i], err)
407+
return nil, fmt.Errorf("failed to remove old log %q: %w", logs[i], err)
408408
}
409409
}
410410
logs = logs[i:]
@@ -413,15 +413,19 @@ func (c *containerLogManager) removeExcessLogs(logs []string) ([]string, error)
413413

414414
// compressLog compresses a log to log.gz with gzip.
415415
func (c *containerLogManager) compressLog(log string) error {
416+
logInfo, err := os.Stat(log)
417+
if err != nil {
418+
return fmt.Errorf("failed to stat log file: %w", err)
419+
}
416420
r, err := c.osInterface.Open(log)
417421
if err != nil {
418-
return fmt.Errorf("failed to open log %q: %v", log, err)
422+
return fmt.Errorf("failed to open log %q: %w", log, err)
419423
}
420424
defer r.Close()
421425
tmpLog := log + tmpSuffix
422-
f, err := c.osInterface.OpenFile(tmpLog, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
426+
f, err := c.osInterface.OpenFile(tmpLog, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, logInfo.Mode())
423427
if err != nil {
424-
return fmt.Errorf("failed to create temporary log %q: %v", tmpLog, err)
428+
return fmt.Errorf("failed to create temporary log %q: %w", tmpLog, err)
425429
}
426430
defer func() {
427431
// Best effort cleanup of tmpLog.
@@ -431,19 +435,19 @@ func (c *containerLogManager) compressLog(log string) error {
431435
w := gzip.NewWriter(f)
432436
defer w.Close()
433437
if _, err := io.Copy(w, r); err != nil {
434-
return fmt.Errorf("failed to compress %q to %q: %v", log, tmpLog, err)
438+
return fmt.Errorf("failed to compress %q to %q: %w", log, tmpLog, err)
435439
}
436440
// The archive needs to be closed before renaming, otherwise an error will occur on Windows.
437441
w.Close()
438442
f.Close()
439443
compressedLog := log + compressSuffix
440444
if err := c.osInterface.Rename(tmpLog, compressedLog); err != nil {
441-
return fmt.Errorf("failed to rename %q to %q: %v", tmpLog, compressedLog, err)
445+
return fmt.Errorf("failed to rename %q to %q: %w", tmpLog, compressedLog, err)
442446
}
443447
// Remove old log file.
444448
r.Close()
445449
if err := c.osInterface.Remove(log); err != nil {
446-
return fmt.Errorf("failed to remove log %q after compress: %v", log, err)
450+
return fmt.Errorf("failed to remove log %q after compress: %w", log, err)
447451
}
448452
return nil
449453
}
@@ -454,7 +458,7 @@ func (c *containerLogManager) rotateLatestLog(ctx context.Context, id, log strin
454458
timestamp := c.clock.Now().Format(timestampFormat)
455459
rotated := fmt.Sprintf("%s.%s", log, timestamp)
456460
if err := c.osInterface.Rename(log, rotated); err != nil {
457-
return fmt.Errorf("failed to rotate log %q to %q: %v", log, rotated, err)
461+
return fmt.Errorf("failed to rotate log %q to %q: %w", log, rotated, err)
458462
}
459463
if err := c.runtimeService.ReopenContainerLog(ctx, id); err != nil {
460464
// Rename the rotated log back, so that we can try rotating it again
@@ -466,7 +470,7 @@ func (c *containerLogManager) rotateLatestLog(ctx context.Context, id, log strin
466470
// log.
467471
klog.ErrorS(renameErr, "Failed to rename rotated log", "rotatedLog", rotated, "newLog", log, "containerID", id)
468472
}
469-
return fmt.Errorf("failed to reopen container log %q: %v", id, err)
473+
return fmt.Errorf("failed to reopen container log %q: %w", id, err)
470474
}
471475
return nil
472476
}

pkg/kubelet/logs/container_log_manager_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,18 @@ func TestCompressLog(t *testing.T) {
370370
testFile.Close()
371371

372372
testLog := testFile.Name()
373+
testLogInfo, err := os.Stat(testLog)
374+
assert.NoError(t, err)
373375
c := &containerLogManager{osInterface: container.RealOS{}}
374376
require.NoError(t, c.compressLog(testLog))
375-
_, err = os.Stat(testLog + compressSuffix)
377+
testLogCompressInfo, err := os.Stat(testLog + compressSuffix)
376378
assert.NoError(t, err, "log should be compressed")
379+
if testLogInfo.Mode() != testLogCompressInfo.Mode() {
380+
t.Errorf("compressed and uncompressed test log file modes do not match")
381+
}
382+
if err := c.compressLog("test-unknown-log"); err == nil {
383+
t.Errorf("compressing unknown log should return error")
384+
}
377385
_, err = os.Stat(testLog + tmpSuffix)
378386
assert.Error(t, err, "temporary log should be renamed")
379387
_, err = os.Stat(testLog)

0 commit comments

Comments
 (0)