MCPcopy Create free account
hub / github.com/containers/image / convertSIFToElements

Function convertSIFToElements

sif/load.go:150–216  ·  view source on GitHub ↗

convertSIFToElements processes sifImage and creates/returns the relevant elements for constructing an OCI-like image: - A path to a tar file containing a root filesystem, - A command to run. The returned tar file path is inside tempDir, which can be assumed to be empty at start, and is exclusively u

(ctx context.Context, sifImage *sif.FileImage, tempDir string)

Source from the content-addressed store, hash-verified

148// at start, and is exclusively used by the current process (i.e. it is safe
149// to use hard-coded relative paths within it).
150func convertSIFToElements(ctx context.Context, sifImage *sif.FileImage, tempDir string) (string, []string, error) {
151 // We could allocate unique names for all of these using os.{CreateTemp,MkdirTemp}, but tempDir is exclusive,
152 // so we can just hard-code a set of unique values here.
153 // We create and/or manage cleanup of these two paths.
154 squashFSPath := filepath.Join(tempDir, "rootfs.squashfs")
155 tarPath := filepath.Join(tempDir, "rootfs.tar")
156 // We only allocate these paths, the user is responsible for cleaning them up.
157 extractedRootPath := filepath.Join(tempDir, "rootfs")
158 scriptPath := filepath.Join(tempDir, "script")
159
160 succeeded := false
161 // It's safe for the Remove calls to happen even before we create the files, because tempDir is exclusive
162 // for our use.
163 // Ideally we would remove squashFSPath immediately after creating extractedRootPath, but we need
164 // to run both creation and consumption of extractedRootPath in the same fakeroot context.
165 // So, overall, this process requires at least 2 compressed copies (SIF and squashFSPath) and 2
166 // uncompressed copies (extractedRootPath and tarPath) of the data, all using up space at the same time.
167 // That's rather unsatisfactory, ideally we would be streaming the data directly from a squashfs parser
168 // reading from the SIF file to a tarball, for 1 compressed and 1 uncompressed copy.
169 defer os.Remove(squashFSPath)
170 defer func() {
171 if !succeeded {
172 os.Remove(tarPath)
173 }
174 }()
175
176 command, injectedScript, err := processDefFile(sifImage)
177 if err != nil {
178 return "", nil, err
179 }
180
181 rootFS, err := sifImage.GetDescriptor(sif.WithPartitionType(sif.PartPrimSys))
182 if err != nil {
183 return "", nil, fmt.Errorf("looking up rootfs from SIF file: %w", err)
184 }
185 // TODO: We'd prefer not to make a full copy of the file here; unsquashfs ≥ 4.4
186 // has an -o option that allows extracting a squashfs from the SIF file directly,
187 // but that version is not currently available in RHEL 8.
188 logrus.Debugf("Creating a temporary squashfs image %s ...", squashFSPath)
189 if err := func() (retErr error) { // A scope for defer
190 f, err := os.Create(squashFSPath)
191 if err != nil {
192 return err
193 }
194 // since we are writing to this file, make sure we handle err on Close()
195 defer func() {
196 closeErr := f.Close()
197 if retErr == nil {
198 retErr = closeErr
199 }
200 }()
201 // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done().
202 if _, err := io.CopyN(f, rootFS.GetReader(), rootFS.Size()); err != nil {
203 return err
204 }
205 return nil
206 }(); err != nil {
207 return "", nil, err

Callers 1

newImageSourceFunction · 0.85

Calls 5

processDefFileFunction · 0.85
createTarFromSIFInputsFunction · 0.85
RemoveMethod · 0.80
CloseMethod · 0.65
SizeMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…