New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
o/configstate, o/snapshotstate: fix handling of nil snap config on snapshot restore #10007
Conversation
eb609e9
to
9a5ce41
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some considerations
a8b3ce0
to
ffe90b9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for this, couple small remarks
ffe90b9
to
a8db7e5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you
@@ -145,7 +145,8 @@ func GetSnapConfig(st *state.State, snapName string) (*json.RawMessage, error) { | |||
func SetSnapConfig(st *state.State, snapName string, snapcfg *json.RawMessage) error { | |||
var config map[string]*json.RawMessage | |||
err := st.Get("config", &config) | |||
isNil := snapcfg == nil || len(*snapcfg) == 0 | |||
// empty nil snapcfg should be an empty message, but deal with "null" as well. | |||
isNil := snapcfg == nil || len(*snapcfg) == 0 || bytes.Compare(*snapcfg, []byte("null")) == 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remove the "bytes.Compare()" here and run the (unit and snapshot-basic spread) tests nothing changes:
index 737421270d..563c5c49ae 100644
--- a/overlord/configstate/config/helpers.go
+++ b/overlord/configstate/config/helpers.go
@@ -146,7 +146,7 @@ func SetSnapConfig(st *state.State, snapName string, snapcfg *json.RawMessage) e
var config map[string]*json.RawMessage
err := st.Get("config", &config)
// empty nil snapcfg should be an empty message, but deal with "null" as well.
- isNil := snapcfg == nil || len(*snapcfg) == 0 || bytes.Compare(*snapcfg, []byte("null")) == 0
+ isNil := snapcfg == nil || len(*snapcfg) == 0
if err == state.ErrNoState {
if isNil {
// bail out early
so either:
a) I did something wrong
b) this is not needed
c) our tests need to improve
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch! The check in the test was not sufficient, added now. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you
Fix for LP #1917870. The root cause is that if snapshot.Conf is nil and is marshaled into json.RawMessage, the later check if serialized value is nil or has len==0 is not working, because json.RawMessage is literally "null". So we put null as the root config of the given snap, and this later explodes in Commit on snap set ..., because we're not expecting nil maps at this level.
The fix avoids marshaling of nil config, but as an extra measure SetSnapConfig() also deals with "null" raw message.