@@ -34,8 +34,6 @@ import (
34
34
"strings"
35
35
"time"
36
36
37
- securejoin "github.com/cyphar/filepath-securejoin"
38
-
39
37
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
40
38
"k8s.io/apimachinery/pkg/util/validation/field"
41
39
)
@@ -229,10 +227,14 @@ func (n *nodeLogQuery) validate() field.ErrorList {
229
227
case len (n .Files ) == 1 && n .options != (options {}):
230
228
allErrs = append (allErrs , field .Invalid (field .NewPath ("query" ), n .Files , "cannot specify file with options" ))
231
229
case len (n .Files ) == 1 :
232
- if fullLogFilename , err := securejoin .SecureJoin (nodeLogDir , n .Files [0 ]); err != nil {
233
- allErrs = append (allErrs , field .Invalid (field .NewPath ("query" ), n .Files , err .Error ()))
234
- } else if _ , err := os .Stat (fullLogFilename ); err != nil {
230
+ if root , err := os .OpenRoot (nodeLogDir ); err != nil {
235
231
allErrs = append (allErrs , field .Invalid (field .NewPath ("query" ), n .Files , err .Error ()))
232
+ } else {
233
+ // root.Close() never returns errors
234
+ defer func () { _ = root .Close () }()
235
+ if _ , err := root .Stat (n .Files [0 ]); err != nil {
236
+ allErrs = append (allErrs , field .Invalid (field .NewPath ("query" ), n .Files , err .Error ()))
237
+ }
236
238
}
237
239
}
238
240
@@ -403,6 +405,30 @@ func newReaderCtx(ctx context.Context, r io.Reader) io.Reader {
403
405
}
404
406
}
405
407
408
+ // heuristicsCopyFileLog returns the contents of the given logFile
409
+ func heuristicsCopyFileLog (ctx context.Context , w io.Writer , logDir , logFileName string ) error {
410
+ f , err := os .OpenInRoot (logDir , logFileName )
411
+ if err != nil {
412
+ return err
413
+ }
414
+ // Ignoring errors when closing a file opened read-only doesn't cause data loss
415
+ defer func () { _ = f .Close () }()
416
+ fInfo , err := f .Stat ()
417
+ if err != nil {
418
+ return err
419
+ }
420
+ // This is to account for the heuristics where logs for service foo
421
+ // could be in /var/log/foo/
422
+ if fInfo .IsDir () {
423
+ return os .ErrNotExist
424
+ }
425
+
426
+ if _ , err := io .Copy (w , newReaderCtx (ctx , f )); err != nil {
427
+ return err
428
+ }
429
+ return nil
430
+ }
431
+
406
432
func safeServiceName (s string ) error {
407
433
// Max length of a service name is 256 across supported OSes
408
434
if len (s ) > maxServiceLength {
0 commit comments