Skip to content

Commit 1f927d6

Browse files
authored
log: Only chmod if permission bits differ; make log dir (#6761)
* log: Only chmod if permission bits differ Follow-up to #6314 and https://caddy.community/t/caddy-2-9-0-breaking-change/27576/11 * Fix test * Refactor FileWriter * Ooooh octal... right...
1 parent 50778b5 commit 1f927d6

File tree

2 files changed

+57
-38
lines changed

2 files changed

+57
-38
lines changed

modules/logging/filewriter.go

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"io"
2121
"math"
2222
"os"
23+
"path/filepath"
2324
"strconv"
2425

2526
"github.com/dustin/go-humanize"
@@ -146,51 +147,68 @@ func (fw FileWriter) WriterKey() string {
146147

147148
// OpenWriter opens a new file writer.
148149
func (fw FileWriter) OpenWriter() (io.WriteCloser, error) {
149-
if fw.Mode == 0 {
150-
fw.Mode = 0o600
150+
modeIfCreating := os.FileMode(fw.Mode)
151+
if modeIfCreating == 0 {
152+
modeIfCreating = 0o600
151153
}
152154

153-
// roll log files by default
154-
if fw.Roll == nil || *fw.Roll {
155-
if fw.RollSizeMB == 0 {
156-
fw.RollSizeMB = 100
157-
}
158-
if fw.RollCompress == nil {
159-
compress := true
160-
fw.RollCompress = &compress
161-
}
162-
if fw.RollKeep == 0 {
163-
fw.RollKeep = 10
164-
}
165-
if fw.RollKeepDays == 0 {
166-
fw.RollKeepDays = 90
167-
}
155+
// roll log files as a sensible default to avoid disk space exhaustion
156+
roll := fw.Roll == nil || *fw.Roll
168157

169-
// create the file if it does not exist with the right mode.
170-
// lumberjack will reuse the file mode across log rotation.
171-
f_tmp, err := os.OpenFile(fw.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(fw.Mode))
158+
// create the file if it does not exist; create with the configured mode, or default
159+
// to restrictive if not set. (lumberjack will reuse the file mode across log rotation)
160+
if err := os.MkdirAll(filepath.Dir(fw.Filename), 0o700); err != nil {
161+
return nil, err
162+
}
163+
file, err := os.OpenFile(fw.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, modeIfCreating)
164+
if err != nil {
165+
return nil, err
166+
}
167+
info, err := file.Stat()
168+
if roll {
169+
file.Close() // lumberjack will reopen it on its own
170+
}
171+
172+
// Ensure already existing files have the right mode, since OpenFile will not set the mode in such case.
173+
if configuredMode := os.FileMode(fw.Mode); configuredMode != 0 {
172174
if err != nil {
173-
return nil, err
175+
return nil, fmt.Errorf("unable to stat log file to see if we need to set permissions: %v", err)
174176
}
175-
f_tmp.Close()
176-
// ensure already existing files have the right mode,
177-
// since OpenFile will not set the mode in such case.
178-
if err = os.Chmod(fw.Filename, os.FileMode(fw.Mode)); err != nil {
179-
return nil, err
177+
// only chmod if the configured mode is different
178+
if info.Mode()&os.ModePerm != configuredMode&os.ModePerm {
179+
if err = os.Chmod(fw.Filename, configuredMode); err != nil {
180+
return nil, err
181+
}
180182
}
183+
}
181184

182-
return &lumberjack.Logger{
183-
Filename: fw.Filename,
184-
MaxSize: fw.RollSizeMB,
185-
MaxAge: fw.RollKeepDays,
186-
MaxBackups: fw.RollKeep,
187-
LocalTime: fw.RollLocalTime,
188-
Compress: *fw.RollCompress,
189-
}, nil
185+
// if not rolling, then the plain file handle is all we need
186+
if !roll {
187+
return file, nil
190188
}
191189

192-
// otherwise just open a regular file
193-
return os.OpenFile(fw.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(fw.Mode))
190+
// otherwise, return a rolling log
191+
if fw.RollSizeMB == 0 {
192+
fw.RollSizeMB = 100
193+
}
194+
if fw.RollCompress == nil {
195+
compress := true
196+
fw.RollCompress = &compress
197+
}
198+
if fw.RollKeep == 0 {
199+
fw.RollKeep = 10
200+
}
201+
if fw.RollKeepDays == 0 {
202+
fw.RollKeepDays = 90
203+
}
204+
return &lumberjack.Logger{
205+
Filename: fw.Filename,
206+
MaxSize: fw.RollSizeMB,
207+
MaxAge: fw.RollKeepDays,
208+
MaxBackups: fw.RollKeep,
209+
LocalTime: fw.RollLocalTime,
210+
Compress: *fw.RollCompress,
211+
}, nil
194212
}
195213

196214
// UnmarshalCaddyfile sets up the module from Caddyfile tokens. Syntax:

modules/logging/filewriter_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"encoding/json"
2121
"os"
2222
"path"
23+
"path/filepath"
2324
"syscall"
2425
"testing"
2526

@@ -77,7 +78,7 @@ func TestFileCreationMode(t *testing.T) {
7778
t.Fatalf("failed to create tempdir: %v", err)
7879
}
7980
defer os.RemoveAll(dir)
80-
fpath := path.Join(dir, "test.log")
81+
fpath := filepath.Join(dir, "test.log")
8182
tt.fw.Filename = fpath
8283

8384
logger, err := tt.fw.OpenWriter()
@@ -92,7 +93,7 @@ func TestFileCreationMode(t *testing.T) {
9293
}
9394

9495
if st.Mode() != tt.wantMode {
95-
t.Errorf("file mode is %v, want %v", st.Mode(), tt.wantMode)
96+
t.Errorf("%s: file mode is %v, want %v", tt.name, st.Mode(), tt.wantMode)
9697
}
9798
})
9899
}

0 commit comments

Comments
 (0)