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
snap: load and validate implicit hooks. #1329
snap: load and validate implicit hooks. #1329
Conversation
22c3425
to
3c7720c
Compare
Implicit hooks are hooks present in the snap but not declared in the snap.yaml. They are loaded along with an installed snap as well as a snap container. Updates: #1586465 Signed-off-by: Kyle Fazzari <kyle@canonical.com>
3c7720c
to
9a71aa8
Compare
ReadFile(relative string) ([]byte, error) | ||
|
||
// ReadDir returns the content of a single directory inside the snap. | ||
ReadDir(path string) ([]os.FileInfo, error) |
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.
Can we avoid os.FileInfo here? With that we force a pretty particular implementation of this method.
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.
Sure, in my use-case I only need the file name, but changing this to []string
limits the amount of information we get out of it, of course. Can you think of something else, or do you just want []string
?
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.
Would the implementations we can think of be reasonable if we had just ListDir(path string) []string?
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.
Yeah I think so, I'll do that. It means they have to do a little more work to figure out if the children are files or directories, etc., but we don't have any requirements for directory walking right now.
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.
Done.
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.
I've been thinking some more about this. What if a snap author forgets to make the hook in question executable? Or has a directory in here instead? Wouldn't we want to know that when loading them info snap.Info
and skip such hooks, or display a warning or error? Using []string
here makes that difficult, as I mentioned before. What do you think?
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.
mmh, we don't do those checks for apps either atm though, I agree that directory vs regular file is a bit borderline here though
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.
@pedronis what do you think? Should we enrich this interface a little so we can get that type of data out of it?
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Also, return []string instead of []os.FileInfo. Signed-off-by: Kyle Fazzari <kyle@canonical.com>
LGTM |
// First of all, check to ensure the hooks directory exists. If it doesn't, | ||
// it's not an error-- there's just nothing to do. | ||
hooksDir := snapInfo.HooksDir() | ||
if _, err := os.Stat(hooksDir); os.IsNotExist(err) { |
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.
You could use osutil.IsDirectory(hooksDir)
here, but the os.Stat() is fine of course.
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.
Ah, good idea.
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.
Done.
Looks very nice overall, just some questions/suggestsions. |
ImplicitSlotsForTests = implicitSlots | ||
ImplicitClassicSlotsForTests = implicitClassicSlots | ||
RelativeHooksDir = relativeHooksDir | ||
AddImplicitHooks = addImplicitHooks |
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.
not sure there's a big win in term of testing of exposing these, instead of calling the Read* functions (that are actually what will be used and call them)
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.
Agreed, done.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
} | ||
|
||
dirPath = path.Clean(dirPath) | ||
pattern := regexp.MustCompile(regexp.QuoteMeta(dirPath) + string(os.PathSeparator) + "?(.+)") |
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.
MustCompile is strange given that dirPath comes from outside, also I would add start/endline anchoring otherwise there may be strange corner cases, also if you exclude / ([^/] instead of .) from the tail end you don't need the check ContainsRune check?
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.
Agreed, though I needed [^/\n\r]
. More succinct indeed.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
} | ||
|
||
dirPath = path.Clean(dirPath) | ||
pattern, err := regexp.Compile("(?m)^/?" + regexp.QuoteMeta(dirPath) + string(os.PathSeparator) + "?([^/\r\n]+)$") |
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.
would like to avoid the ?s here if possible. What about --dest "_"
and prefixPath = path.Join("_", dirPath)
and in the regexp just do: "(?m)^" + QuoteMeta(prefixPath) + "/([^...]+)$"
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.
Very good, done.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
return nil, err | ||
} | ||
|
||
prefixPath := filepath.Join("_", dirPath) |
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.
this can be path not filepath
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.
Done.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
prefixPath := filepath.Join("_", dirPath) | ||
pattern, err := regexp.Compile("(?m)^" + regexp.QuoteMeta(prefixPath) + "/([^/\r\n]+)$") | ||
if err != nil { | ||
return nil, err |
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.
would prefix this somehow: return nil, fmt.Errorf("internal error: cannot compile squashfs list dir regexp for %q: %v", dirPath, err) or something
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.
Done.
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Signed-off-by: Kyle Fazzari <kyle@canonical.com>
Implicit hooks are hooks present in the snap but not declared in the snap.yaml. This PR makes progress on LP: #1586465 by loading them along with an installed snap as well as a snap container.