-
Notifications
You must be signed in to change notification settings - Fork 395
sif: initial sif transport implementation #1402
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
Conversation
3530027 to
bbfe19f
Compare
|
@yhcote @Vrotberg @mtrmac would love to collaborate with you all on this. We're actively maintaining a |
@tri-adam I checked quickly and saw two different repos with SIF updates. Since the current feature requires simple data object dumps from the SIF file the current import is sufficient. The best course of action right now to get the ball rolling is to at least get this initial PR in and let the community decide which improvements (some already listed in the PR comment) they want to see next. That PR needs a few touch ups but it should be done this week. |
Signed-off-by: Yannick Cote <[email protected]>
Bring sif code in the repo instead of pulling it in at build time. Resolves PR code review discussion. Signed-off-by: Yannick Cote <[email protected]>
Signed-off-by: Yannick Cote <[email protected]>
Signed-off-by: Yannick Cote <[email protected]>
bbfe19f to
5418eb1
Compare
Yes, there is
Unless I'm missing something, using Anyways, just want to make it crystal clear that we're open to collaboration on this. Excited to see where it goes, in any case! |
|
@mtrmac @vrothberg Can we get a fresh review on this? |
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 didn’t check the sif/sif package in detail yet — I do default to thinking we should use the maintained external dependency instead, but I’ll check the code etc. first.
Highlights:
Sprintfon untrusted input- Do we want a temporary compressed representation at all?
- Removing on-disk data immediately after use
- Policy namespaces are inconsistent (and must have tests even the final design is trivial)
| // LoadContainerFp is responsible for loading a SIF container file. It takes | ||
| // a *os.File pointing to an opened file, and whether the file is opened as | ||
| // read-only for arguments. | ||
| func LoadContainerFp(fp *os.File, rdonly bool) (fimg FileImage, err 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.
None of this looks like something that should be a committed part of the stable c/image API.
Either move the subpackage code to sif/internal (or even sif/internal/sif), or perhaps use the external dependency as discussed elsewhere.
| // LICENSE file distributed with the sources of this project regarding your | ||
| // rights to use or distribute this software. | ||
|
|
||
| // +build linux |
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.
Absolutely non-blocking:
Which parts are Linux-specific? The syscall uses of Mmap?
It would be attractive to make this usable on macOS or Windows workstations without a Linux VM.
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.
Just removing these build conditionals, the code seems to at least build fine on macOS.
Of course things like unsquashfs or fakeroot might not be available — but the error handling needs to be user-acceptable for a Linux only version as well. At least from a very quick search, both seem to be packaged in Homebrew.
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.
fakeroot does exist in homebrew, but it installs with
Warning: fakeroot has been deprecated because it does not build!
and it also doesn’t work — in wildly unpredictable ways (sometimes files are not created, sometimes chown fails with EPERM, sometimes chown doesn’t fail but doesn’t do anything).
So making this Linux-only seems reasonable for now. (Ideally we shouldn’t need fakeroot, and do the conversion from SquashFS to tar most in-memory.)
| // The sif transport is registered by sif*.go | ||
| // The ostree transport is registered by ostree*.go | ||
| // The storage transport is registered by storage*.go |
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.
Please keep the comments in alphabetical order.
| @@ -0,0 +1,121 @@ | |||
| // +build linux | |||
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.
Due to the impact on signature verification, we require the Transport implementations to have pretty close to 100% test coverage. Those tests can mostly be copy&pasted from similar sources as this file (dir/docker/archive).
| @@ -0,0 +1,121 @@ | |||
| // +build linux | |||
|
|
|||
| package sifimage | |||
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.
Shouldn’t the package name match the directory name?
| searchDesc := sif.Descriptor{Datatype: sif.DataDeffile} | ||
| resultDescs, _, err := image.fimg.GetFromDescr(searchDesc) | ||
| if err == nil && resultDescs != nil { | ||
| // we assume in practice that typical SIF files don't hold multiple deffiles |
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.
Should there be a warning, or at least a debug log, in that case?
| if err == nil && resultDescs != nil { | ||
| // we assume in practice that typical SIF files don't hold multiple deffiles | ||
| image.deffile = resultDescs[0] | ||
| image.defReader = io.NewSectionReader(image.fimg.Fp, image.deffile.Fileoff, image.deffile.Filelen) |
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.
defReader is only used in generateConfig immediately below, so maybe it can just be a local variable.
| searchDesc = sif.Descriptor{Datatype: sif.DataEnvVar} | ||
| resultDescs, _, err = image.fimg.GetFromDescr(searchDesc) | ||
| if err == nil && resultDescs != nil { | ||
| // we assume in practice that typical SIF files don't hold multiple EnvVar sets |
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.
Should there be a warning, or at least a debug log, in that case?
| // look for an environment variable set object | ||
| searchDesc = sif.Descriptor{Datatype: sif.DataEnvVar} | ||
| resultDescs, _, err = image.fimg.GetFromDescr(searchDesc) | ||
| if err == nil && resultDescs != nil { | ||
| // we assume in practice that typical SIF files don't hold multiple EnvVar sets | ||
| image.env = resultDescs[0] | ||
| image.envReader = io.NewSectionReader(image.fimg.Fp, image.env.Fileoff, image.env.Filelen) | ||
| } |
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 can’t see any use of .env or .envReader. What does this code do?
| ) | ||
|
|
||
| var ( | ||
| sifLoggerBuf bytes.Buffer |
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.
Is this available in any way? I can’t see a way to read this data, which makes the logger pointless.
(c/image otherwise uses logrus).
| if err = image.generateRunscript(); err != nil { | ||
| return errors.Wrap(err, "generating runscript") | ||
| } | ||
| image.cmdlist = []string{"/podman/runscript"} |
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.
image.cmdlist serves two different purposes — a list of bash commands (e.g. input to generateRunscript, and a single command to be by the runtime. Those should be two separate variables.
| return nil | ||
| } | ||
|
|
||
| func (image SifImage) GetConfig(config *imgspecv1.Image) 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.
The name of this function doesn’t match what it does. Maybe a ) Command() []string that just returns the command to run?
|
@yhcote @tri-adam Looking at this PR’s if string(fimg.Header.Version[:HdrVersionLen-1]) > HdrVersion {
return fmt.Errorf("invalid SIF file: Version %s want <= %s", fimg.Header.Version, HdrVersion)
}
…
HdrVersion = "02" // SIF SPEC VERSION(≤ , and 2) vs. https://github.com/sylabs/sif/blob/e807689a1a94304812a6c20573d0d11484b4e2af/pkg/sif/load.go#L29-L31 and https://github.com/sylabs/sif/blob/e807689a1a94304812a6c20573d0d11484b4e2af/pkg/sif/sif.go#L108-L114 (strict equality, and 1). What’s that about? Obviously a file with version "1" passes both checks, so at least that’s good. Is that the only one that matters? I see sylabs/sif@f68560d exists in various repos, and then there’s sylabs/sif@7441391 . (Speaking purely for myself in personal capacity, I don’t really want to dig up historical controversies, if any, and especially I’d prefer if c/image didn’t end up having to play arbiter between competing variants of a format, or worse, having to maintain its own private copy that has to do non-obvious workarounds to accept all of those competing variants at the same time. I’m really hoping for something like “$answer is the obviously correct one, some of the code is just behind”…) |
|
Hi @mtrmac @yhcote (@tri-adam) The HdrVersion '01' is the one that really makes sense here, as it's the prevailing version. Regrettably during the development of the early 3.x releases of Singularity there were some changes like this one (the increment, followed by reversion over the increment) that are not great, in hindsight... The SIF v1.0.3 tag that contains the reversion from 02->01 in sylabs/sif@7441391 was first included in Singularity 3.2.0. Versions since then, including current versions of Singularity, are creating SIFs with a header version of Essentially all SIF containers you would find in the wild will say I'll defer to @tri-adam r.e. the version check in the current SIF code. |
|
Further to my previous comment.... Singularity v3.1.1 used SIF v1.0.2, in which HdrVersion '01' was in effect (before the increment). Singularity v3.2.0 used SIF v1.0.3, in which HdrVersion '01' was in effect (after the reversion). So, we had no official tagged release that should have given a HdrVersion '02' SIF image. They should only appear if someone had built from development code pulling in SIF at that point. The code pulled into containers/image in this PR wasn't used in a release of Singularity. |
Thanks, that’s very helpful. |
|
(Accidentally sent message, see below for the finished one.) |
For the record, looking at the v1.7.0, v2.0.0, and latest common v2.2.3 tags, that seems true enough — there are some differences between the corresponding tags, but mostly just a timing difference (a commit missing from one version but added later, or the like), and almost all of the new code seems cherry-picked from the Sylabs repo. |
Comparing with the current PR, I think Using the external library would also not drag in any extra dependencies. |
@tri-adam Could you sign this commit ( |
|
To test this, e.g. # This is probably not the right way to download the image, it’s just a guess that seems to work
curl -L 'https://library.sylabs.io/v1/imagefile/library/default/lolcow:latest?arch=amd64' -o lolcow.sif
bin/skopeo copy --debug sif:lolcow.sif dir:t
podman run --privileged dir:tor, of course, directly |
@mtrmac done, please see #1436. |
This implements the support for inbound SIF files in the image package.