Skip to content

feat: select and validate manifest#288

Open
upils wants to merge 5 commits into
canonical:mainfrom
upils:feat/select-manifest
Open

feat: select and validate manifest#288
upils wants to merge 5 commits into
canonical:mainfrom
upils:feat/select-manifest

Conversation

@upils
Copy link
Copy Markdown
Collaborator

@upils upils commented Apr 20, 2026

  • Have you signed the CLA?

This PR is the first step to enable Chisel recuting a rootfs. It adds the ability to
select a manifest from the given rootfs based on the release. If a manifest is
found, the slices it lists are added to the slices requested by the user. The rest
of the cutting process is unchanged for now.

This work was split from #264.

Comment thread internal/slicer/slicer.go Outdated
Comment on lines +553 to +569
// SelectValidManifest looks in the targetDir for manifests declared in the
// release, reads and validates those found. The selection ensures that all
// valid manifests found are identical, so only one is kept and returned.
//
// A file matching a manifest path declared in the release is considered valid
// if it is a zstd file, readable by manifest.Read (with a known schema
// version) and successfully validated by manifestutil.Validate.
//
// Not finding any manifest (valid or not) means the targetDir cannot be
// considered as previously produced by Chisel for the given release.
//
// Finding only manifests with unknown schema version means the targetDir may
// have been produced by Chisel, but possibly by a future/incompatible version.
// Chisel cannot safely proceed and so errors out.
//
// Finding multiple manifests, with at least one valid means Chisel can proceed,
// ignoring unknown ones.
Copy link
Copy Markdown
Collaborator Author

@upils upils Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Note to reviewer] This reworked comment addresses the following review comment:

This is not a useful comment. Any misinformed person can tell that what "select valid manifest" does is to "return a valid manifest". As a rule, we always try to write comments that inform what is not obvious from the code, and if we cannot do that, we avoid the comment. That's not the case here, though.. there's a lot to be said about where the manifest is being selected, how it's being selected, what does it even mean to be valid, etc. Succinct is good, but it needs to be clear, terse, informative.

Please spend a moment or two thinking about this and digesting it so I don't need to bother you too much with comments in the future. :)

From #264 (comment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole text is much better, thanks.

That last sentence is both repeating what was already said, and being slightly misleading in that it contradicts what was said earlier in the very first sentence. So perhaps just drop it.

Comment thread internal/slicer/slicer.go
Comment thread internal/slicer/slicer.go
// ignoring unknown ones.
func SelectValidManifest(targetDir string, release *setup.Release) (*manifest.Manifest, error) {
targetDir = filepath.Clean(targetDir)
if !filepath.IsAbs(targetDir) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Note to reviewer]: Previous review comment:

That feels super sketchy. We pretty much never take into account the current directory, except on the very entry point of the overall process. This entry point is the CLI main function, not a library function deep into the implementation. The kinds of bugs that result from this kind of logic tend to go to the news.

From #264 (comment)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is replicating the piece of code at the beginning of Run, which is the only other place we take the current working dir into account. SelectValidManifest is part of the API exposed by slicer and is called at the same level as Run. SelectValidManifest is also expected to be called before Run. We also want both to target the same directory.

I wanted to avoid refactoring Run in this PR but what do you think of extracting this logic of "correcting" the targetDir in a function so it can be done in a consistent way in the 2 places we need to do it?

Otherwise, this logic could be extracted out of Run and moved in cmd_cut.go. However it would change the behavior of Run and would make it riskier to use I think.

From #264 (comment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just attempt to explain why the code looks like this without actually addressing the concern from the original comment:

That feels super sketchy. We pretty much never take into account the current directory, except on the very entry point of the overall process. This entry point is the CLI main function, not a library function deep into the implementation. The kinds of bugs that result from this kind of logic tend to go to the news.

This is also the third time I'm saying this in reviews or in our calls. Is the plan to push this for review until it passes? :)

If you've seen this being done elsewhere, then let's also fix that elsewhere, rather than making it worse.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reworked it, with an hopefully safer approach.

The caller, for now only Execute in cmd_cut.go, is now responsible for doing the path modification if the received target dir is not absolute. To limit risks of cutting in an ambiguous/unexpected target dir, slicer.Run is still checking the received target dir is absolute and returns an internal error if not. Out of consistency SelectValidManifest is doing the same even though it is not writing anything, so this check is not strictly necessary.

//
// Wildcard characters can only appear at the end as **, and the path before
// those wildcards must be a directory.
func validateManifestPath(path string, info setup.PathInfo) (string, error) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Note to reviewer]: This addresses the previous review comment:

This is too loose. Imagine what happens if path is "/hmm/oops**", for instance, or just "/oops".

We need to be strict about how a manifest path looks like. Hopefully this is already the case elsewhere so there's already a pattern to follow. If not, please let me know.

From #264 (comment)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a validateManifestPath function verifying that the received path matches our definition of a valid manifest path before doing any manipulation on it. This function is now used in FindPaths and FindPathsInRelease. I also added a couple of tests to make sure the issue you pointed out was handled properly.

From #264 (comment)

@upils upils added the Priority Look at me first label Apr 20, 2026
Comment thread internal/slicer/slicer.go Outdated
return pkgArchive, nil
}

type NoManifestError struct {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Note to reviewer] This error type is returned in SelectValidManifest in the two situations where the caller can recover from the error, as it is done in cmd_cut.go.
I am conflicted on the usefulness of the message field. On one hand in the only call site of SelectValidManifest, the message is ignored. On the other hand, I think it makes sense for future consumers of this API to be able to display these different error messages.

What do you think?

(discussion initially started in #264 (comment))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field would be okay if we were making good use of it, but all this is being used for is two variations of "cannot find manifest file", so that's indeed not useful right now.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I replaced it with a named error.

@upils upils mentioned this pull request Apr 20, 2026
1 task
Comment thread internal/slicer/slicer.go
// ignoring unknown ones.
func SelectValidManifest(targetDir string, release *setup.Release) (*manifest.Manifest, error) {
targetDir = filepath.Clean(targetDir)
if !filepath.IsAbs(targetDir) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just attempt to explain why the code looks like this without actually addressing the concern from the original comment:

That feels super sketchy. We pretty much never take into account the current directory, except on the very entry point of the overall process. This entry point is the CLI main function, not a library function deep into the implementation. The kinds of bugs that result from this kind of logic tend to go to the news.

This is also the third time I'm saying this in reviews or in our calls. Is the plan to push this for review until it passes? :)

If you've seen this being done elsewhere, then let's also fix that elsewhere, rather than making it worse.

Comment thread internal/slicer/slicer.go Outdated
return pkgArchive, nil
}

type NoManifestError struct {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field would be okay if we were making good use of it, but all this is being used for is two variations of "cannot find manifest file", so that's indeed not useful right now.

Comment thread internal/slicer/slicer.go Outdated
// version) and successfully validated by manifestutil.Validate.
//
// Not finding any manifest (valid or not) means the targetDir cannot be
// considered as previously produced by Chisel for the given release.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can drop this part. Not finding a valid manifest simply means we cannot find a valid and useful manifest to continue. We don't need to attempt to explain what it means otherwise. The manifest might have been produced by an old version of Chisel that we do not support anymore, or whatever else.

Comment thread internal/slicer/slicer.go Outdated
Comment on lines +553 to +569
// SelectValidManifest looks in the targetDir for manifests declared in the
// release, reads and validates those found. The selection ensures that all
// valid manifests found are identical, so only one is kept and returned.
//
// A file matching a manifest path declared in the release is considered valid
// if it is a zstd file, readable by manifest.Read (with a known schema
// version) and successfully validated by manifestutil.Validate.
//
// Not finding any manifest (valid or not) means the targetDir cannot be
// considered as previously produced by Chisel for the given release.
//
// Finding only manifests with unknown schema version means the targetDir may
// have been produced by Chisel, but possibly by a future/incompatible version.
// Chisel cannot safely proceed and so errors out.
//
// Finding multiple manifests, with at least one valid means Chisel can proceed,
// ignoring unknown ones.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole text is much better, thanks.

That last sentence is both repeating what was already said, and being slightly misleading in that it contradicts what was said earlier in the very first sentence. So perhaps just drop it.

Comment thread internal/slicer/slicer.go Outdated
}
manifestPaths := manifestutil.FindPathsInRelease(release)
if len(manifestPaths) == 0 {
return nil, &NoManifestError{message: "no manifest generated for the release"}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error doesn't sound right.. we are not generating manifests here.

Comment thread internal/slicer/slicer.go Outdated
if foundUnknownSchema {
return nil, fmt.Errorf("cannot select a manifest: all manifests found use unknown schema")
} else {
return nil, &NoManifestError{message: "no valid manifest found in directory"}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"cannot find valid manifest file"

Comment thread internal/slicer/slicer.go Outdated
}
if selected == nil {
if foundUnknownSchema {
return nil, fmt.Errorf("cannot select a manifest: all manifests found use unknown schema")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"cannot select a manifest: schema version is unknown"

Comment thread internal/slicer/slicer.go
var selectedHash string
var selectedPath string
foundUnknownSchema := false
for _, manifestPath := range manifestPaths {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop might be more readable if the logic for a single file gets moved to its own function.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I extracted it to a tryLoadManifest function, making the logic of SelectValidManifest a bit easier to reason about.

Comment thread internal/slicer/slicer.go
@upils upils requested a review from letFunny April 28, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Priority Look at me first

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants