Conversation
Codecov Report
@@ Coverage Diff @@
## develop #2286 +/- ##
==========================================
+ Coverage 61.26% 62.67% +1.4%
==========================================
Files 197 215 +18
Lines 16260 17608 +1348
==========================================
+ Hits 9962 11035 +1073
- Misses 5431 5659 +228
- Partials 867 914 +47
|
|
Do you think it make sense to test new behaviour? |
I think it basically always makes sense to test any new behaviour. I'm not sure in this case though: The methods in question are private and it would be like testing the correctness of the standard go-library (and if we can properly write to the filesystem where the test is running etc). But let me add a few lines to the existing |
libs/autofile/autofile.go
Outdated
| if err != nil { | ||
| return err | ||
| } | ||
| fInf, err := file.Stat() |
There was a problem hiding this comment.
May I suggest a better name: fileInfo? It's a bit hard to decipher fInf.
There was a problem hiding this comment.
I will change myself if that's ok
libs/db/fsdb.go
Outdated
| return err | ||
| } | ||
| defer f.Close() | ||
| fInf, err := f.Stat() |
libs/autofile/autofile_test.go
Outdated
| // Manually modify file permissions, close, and reopen using autofile: | ||
| // We expect the file permissions to be changed back to the intended perms. | ||
| file, err := ioutil.TempFile("", "permission_test") | ||
| if err != nil { |
There was a problem hiding this comment.
Would be nice to use https://github.com/stretchr/testify here to simplify code
require.NoError(t, err)
ValarDragon
left a comment
There was a problem hiding this comment.
This change looks fine to me, but I'd prefer that we don't change the permission mid-session. Most other tools I use don't do this, they just error on invalid perms. (e.g. things that involve ssh keys) This is going to be an edge case that may frustrate users if they want these files to have certain perms, and they get silently changed. If we prefer to auto-upgrade the perms, we should at least log that we are doing so.
This is kind of minor, so I'm fine with the overall change being merged. (Hence the approve)
|
On the second thought, I don't think we should try to fix errors one level above Tendermint. If someone hacked the OS and changed file's permissions, then owners are screwed in any case. If it's due to some glitch, again it's not the Tendermint task to log that permissions got changed (although it may be nice). |
|
An alternative would be to error if the file permissions changed (as suggested in the related issue #2285). Could be a sentinel error so the caller can handle it and give the user a proper error message on the command-line / the UI. I do not think we should just ignore it if the permissions changed (either due some glitch or a hack). |
@ValarDragon did you request changes by accident then? |
keep in mind that if Tendermint loses permission to write to that file, it will panic. so we're only talking about group rw/other rw permissions. |
That said, the reasonable thing to do is to log a warning (e.g. "%s permissions were modified (was: %v, become: %v)"). Don't think we should panic if Tendermint still has a right to write to the file. |
- if we can't read the file, we'll still panic
libs/autofile/autofile_test.go
Outdated
| err = af.Close() | ||
| require.NoError(t, err) | ||
| require.Error(t, err) | ||
| t.Log(err) |
There was a problem hiding this comment.
Will print:
expected file permissions: -rw-------, got: -rwxr-xr-x: file permissions changed
libs/autofile/autofile.go
Outdated
| return err | ||
| } | ||
| return errors.WithMessage(PermissionsChangedErr, | ||
| fmt.Sprintf("expected file permissions: %v, got: %v", autoFilePerms, fileInfo.Mode())) |
There was a problem hiding this comment.
does it make sense to print the filename too?
There was a problem hiding this comment.
Yes, now it prints:
file: [/var/folders/qf/7nq2274n50v5x9s2y4jcmfgm0000gn/T/permission_test343097720]
expected file permissions: -rw-------, got: -rwxr-xr-x
libs/autofile/autofile.go
Outdated
| autoFilePerms = os.FileMode(0600) | ||
| ) | ||
|
|
||
| var PermissionsChangedErr = errors.New("file permissions changed") |
libs/autofile/autofile.go
Outdated
| "sync" | ||
| "time" | ||
|
|
||
| "github.com/pkg/errors" |
There was a problem hiding this comment.
There was a problem hiding this comment.
I started with that but it was annoyingly difficult to sth simple as just annotating an error with additional info (the formatted string). Maybe, I was just using it wrong.
There was a problem hiding this comment.
Is there a simple example somewhere?
I want a sentinel error as above PermissionsChangedErr (such that the caller can check against it) and simply annotate it with more info. I can use ErrorWrap but I do not see a way to get the annotated content without the whole stack trace a la:
=== RUN TestOpenAutoFilePerms
--- PASS: TestOpenAutoFilePerms (0.00s)
autofile_test.go:85: --= Error =--
Data: "file permissions changed"
Msg Traces:
0 /Users/ismail/go/src/github.com/tendermint/tendermint/libs/autofile/autofile.go:133 - [/var/folders/qf/7nq2274n50v5x9s2y4jcmfgm0000gn/T/permission_test853068086]: expected file permissions : -rw-------, got: -rwxr-xr-x
Stack Trace:
0 /Users/ismail/go/src/github.com/tendermint/tendermint/libs/common/errors.go:14
1 /Users/ismail/go/src/github.com/tendermint/tendermint/libs/autofile/autofile.go:133
2 /Users/ismail/go/src/github.com/tendermint/tendermint/libs/autofile/autofile.go:60
3 /Users/ismail/go/src/github.com/tendermint/tendermint/libs/autofile/autofile_test.go:82
4 /usr/local/Cellar/go/1.10.3/libexec/src/testing/testing.go:777
5 /usr/local/Cellar/go/1.10.3/libexec/src/runtime/asm_amd64.s:2362
--= /Error =--
PASS
That's way to verbose for this simple case. Basically, we just want the first msg trace (as possible with github.com/pkg/errors via errors.WithMessage). cmn.NewErrorWithData doesn't provide sth. similar either. NewError can not keep the orig. error/Error.
Am I missing sth. obvious here?
There was a problem hiding this comment.
I just got rid of github.com/pkg/errors and type aliased a string. I think that is the simplest way to handle this.
xla
left a comment
There was a problem hiding this comment.
Some changes to make the code more idiomatic.
libs/autofile/autofile.go
Outdated
| ) | ||
|
|
||
| // PermissionsChangedErr occurs if the file permission have changed since the file was created. | ||
| type PermissionsChangedErr string |
There was a problem hiding this comment.
Prefixing of Err is the de facto standard, compared to suffxing: PermissionsChangedErr -> ErrPermissionsChanged.
libs/autofile/autofile.go
Outdated
| return err | ||
| } | ||
| if fileInfo.Mode() != autoFilePerms { | ||
| return PermissionsChangedErr(fmt.Sprintf("file: [%v]\nexpected file permissions: %v, got: %v", |
There was a problem hiding this comment.
This error string construction might be better placed in the Error method of the error type and carry the relevant info in a struct:
type ErrPermissionsChanged struct {
name string
expected, got os.FileMode
}
func (e ErrPermissionsChanged) Error() string {
return fmt.Sprintf(
"file: [%v]\nexpected file permissions: %v, got: %v",
e.name,
e.expected,
e.got,
)
}
libs/autofile/autofile.go
Outdated
| return err | ||
| } | ||
| if fileInfo.Mode() != autoFilePerms { | ||
| return PermissionsChangedErr(fmt.Sprintf("file: [%v]\nexpected file permissions: %v, got: %v", |
There was a problem hiding this comment.
Additionally this way of formatting, I know brought it up before, is confusing. There is no clear rule to when to break a line and recognising where one construct starts and another requires a lot of effort. More consistently it should look like this:
return PermissionsChangedErr(
fmt.Sprintf(
"file: [%v]\nexpected file permissions: %v, got: %v",
file.Name(),
autoFilePerms,
fileInfo.Mode(),
),
)This is allows for faster reading and faster editing of the code.
libs/db/fsdb.go
Outdated
| ) | ||
|
|
||
| // PermissionsChangedErr occurs if the file permission have changed since the file was created. | ||
| type PermissionsChangedErr string |
There was a problem hiding this comment.
Prefix over suffix as above.
Is there a reason that both packages need to export their own version of the same error, can those be consolidated?
There was a problem hiding this comment.
Of course they could. What package would be a good place? libs/common/errror_types.go ?
There was a problem hiding this comment.
libs/common does have errors, but comes with a lot of other things. I'd say a central errors package would be good, maybe for now under libs.
- prefix instead of suffix - add state to err and construct formatting in Error() method
- move error to libs/errors
The current behavior is panic if autofile#openFile returns an error. But for ErrPermissionsChanged, we should warn a user that permissions are different (given we still retain the ability to write to the file). This also modifies fsdb. Issue from our Riot: ``` S: `Panicked on a Sanity Check: Error opening Mempool wal file: file: [/tendermint/mytestnet/node0/data/mempool.wal/wal] expected file permissions: -rw-------, got: -rwxrwxrwx` M: somebody/something changed wal file permissions S: I'm running a docker-compose setup with 4 nodes, It used to work with tendermint 22.0 and started to break when upgraded to tendermint 25.0 ``` Refs #2286
The current behavior is panic if autofile#openFile returns an error. But for ErrPermissionsChanged, we should warn a user that permissions are different (given we still retain the ability to write to the file). This also modifies fsdb. Issue from our Riot: ``` S: `Panicked on a Sanity Check: Error opening Mempool wal file: file: [/tendermint/mytestnet/node0/data/mempool.wal/wal] expected file permissions: -rw-------, got: -rwxrwxrwx` M: somebody/something changed wal file permissions S: I'm running a docker-compose setup with 4 nodes, It used to work with tendermint 22.0 and started to break when upgraded to tendermint 25.0 ``` Refs #2286
current code results in panic and we certainly don't want that. #2286 (comment)
current code results in panic and we certainly don't want that. #2286 (comment)
current code results in panic and we certainly don't want that. tendermint#2286 (comment)
current code results in panic and we certainly don't want that. #2286 (comment)
current code results in panic and we certainly don't want that. tendermint/tendermint#2286 (comment)
Resolves #2285