Skip to content

Commit 0d8d0de

Browse files
author
Kern Walster
committed
Refactor SOCI Init logic
This change moves most of the SOCI init logic out of `SociContext.Init` into `fs.fetchSociIndex`. This is to reduce the number of args we need to sent to `SociContext.Init`. There are 2 logic changes here: 1. Remove the cached error lock on `SociContext`. `sync.Once` guarantees that no call to `Do` will return until exactly 1 executes the function. Therefore, there was never any concurrent access as the write to the cached error will always happen before any read. 2. The SOCI index digest is parsed rather than casted to a digest.Digest. Signed-off-by: Kern Walster <walster@amazon.com>
1 parent fc8257f commit 0d8d0de

1 file changed

Lines changed: 52 additions & 54 deletions

File tree

fs/fs.go

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -298,76 +298,29 @@ func NewFilesystem(ctx context.Context, root string, cfg config.FSConfig, opts .
298298

299299
type sociContext struct {
300300
cachedErr error
301-
cachedErrMu sync.RWMutex
302301
bgFetchPauseOnce sync.Once
303302
fetchOnce sync.Once
304303
sociIndex *soci.Index
305304
imageLayerToSociDesc map[string]ocispec.Descriptor
306305
fuseOperationCounter *layer.FuseOperationCounter
307306
}
308307

309-
func (c *sociContext) Init(fsCtx context.Context, ctx context.Context, imageRef, indexDigest, imageManifestDigest string, store store.Store, fuseOpEmitWaitDuration time.Duration, client *http.Client) error {
310-
var retErr error
308+
func (c *sociContext) Init(ctx context.Context, fs *filesystem, imageRef, indexDigest, imageManifestDigest string, client *http.Client) error {
311309
c.fetchOnce.Do(func() {
312-
defer func() {
313-
if retErr != nil {
314-
c.cachedErrMu.Lock()
315-
c.cachedErr = retErr
316-
c.cachedErrMu.Unlock()
317-
}
318-
}()
319-
320-
refspec, err := reference.Parse(imageRef)
321-
if err != nil {
322-
retErr = err
323-
return
324-
}
325-
326-
remoteStore, err := newRemoteStore(refspec, client)
310+
index, err := fs.fetchSociIndex(ctx, imageRef, indexDigest, imageManifestDigest, client)
327311
if err != nil {
328-
retErr = err
329-
return
330-
}
331-
332-
client := NewOCIArtifactClient(remoteStore)
333-
indexDesc := ocispec.Descriptor{
334-
Digest: digest.Digest(indexDigest),
335-
}
336-
337-
if indexDigest == "" {
338-
log.G(ctx).Info("index digest not provided, making a Referrers API call to fetch list of indices")
339-
imgDigest, err := digest.Parse(imageManifestDigest)
340-
if err != nil {
341-
retErr = fmt.Errorf("unable to parse image digest: %w", err)
342-
}
343-
344-
desc, err := client.SelectReferrer(ctx, ocispec.Descriptor{Digest: imgDigest}, defaultIndexSelectionPolicy)
345-
if err != nil {
346-
retErr = fmt.Errorf("%w: cannot fetch list of referrers: %w", snapshot.ErrNoIndex, err)
347-
return
348-
}
349-
indexDesc = desc
350-
}
351-
352-
log.G(ctx).WithField("digest", indexDesc.Digest.String()).Infof("fetching SOCI artifacts using index descriptor")
353-
354-
index, err := FetchSociArtifacts(ctx, refspec, indexDesc, store, remoteStore)
355-
if err != nil {
356-
retErr = fmt.Errorf("%w: error trying to fetch SOCI artifacts: %w", snapshot.ErrNoIndex, err)
312+
c.cachedErr = err
357313
return
358314
}
359315
c.sociIndex = index
360316
c.populateImageLayerToSociMapping(index)
361317

362318
// Create the FUSE operation counter.
363319
// Metrics are emitted after a wait time of fuseOpEmitWaitDuration.
364-
c.fuseOperationCounter = layer.NewFuseOperationCounter(digest.Digest(imageManifestDigest), fuseOpEmitWaitDuration)
365-
go c.fuseOperationCounter.Run(fsCtx)
320+
c.fuseOperationCounter = layer.NewFuseOperationCounter(digest.Digest(imageManifestDigest), fs.fuseMetricsEmitWaitDuration)
321+
go c.fuseOperationCounter.Run(fs.ctx)
366322
})
367-
c.cachedErrMu.RLock()
368-
retErr = c.cachedErr
369-
c.cachedErrMu.RUnlock()
370-
return retErr
323+
return c.cachedErr
371324
}
372325

373326
func (c *sociContext) populateImageLayerToSociMapping(sociIndex *soci.Index) {
@@ -442,10 +395,55 @@ func (fs *filesystem) getSociContext(ctx context.Context, imageRef, indexDigest,
442395
if !ok {
443396
return nil, fmt.Errorf("could not load index: fs soci context is invalid type for %s", indexDigest)
444397
}
445-
err := c.Init(fs.ctx, ctx, imageRef, indexDigest, imageManifestDigest, fs.contentStore, fs.fuseMetricsEmitWaitDuration, client)
398+
err := c.Init(ctx, fs, imageRef, indexDigest, imageManifestDigest, client)
446399
return c, err
447400
}
448401

402+
func (fs *filesystem) fetchSociIndex(ctx context.Context, imageRef, indexDigest, imageManifestDigest string, client *http.Client) (*soci.Index, error) {
403+
refspec, err := reference.Parse(imageRef)
404+
if err != nil {
405+
return nil, err
406+
}
407+
408+
remoteStore, err := newRemoteStore(refspec, client)
409+
if err != nil {
410+
return nil, err
411+
}
412+
413+
var indexDesc ocispec.Descriptor
414+
if indexDigest == "" {
415+
log.G(ctx).Info("index digest not provided, making a Referrers API call to fetch list of indices")
416+
imgDigest, err := digest.Parse(imageManifestDigest)
417+
if err != nil {
418+
return nil, fmt.Errorf("unable to parse image digest: %w", err)
419+
}
420+
421+
artifactClient := NewOCIArtifactClient(remoteStore)
422+
423+
desc, err := artifactClient.SelectReferrer(ctx, ocispec.Descriptor{Digest: imgDigest}, defaultIndexSelectionPolicy)
424+
if err != nil {
425+
return nil, fmt.Errorf("%w: cannot fetch list of referrers: %w", snapshot.ErrNoIndex, err)
426+
}
427+
indexDesc = desc
428+
} else {
429+
dg, err := digest.Parse(indexDigest)
430+
if err != nil {
431+
return nil, fmt.Errorf("%w: unable to parse SOCI index digest: %w", snapshot.ErrNoIndex, err)
432+
}
433+
indexDesc = ocispec.Descriptor{
434+
Digest: dg,
435+
}
436+
}
437+
438+
log.G(ctx).WithField("digest", indexDesc.Digest.String()).Infof("fetching SOCI artifacts using index descriptor")
439+
440+
index, err := FetchSociArtifacts(ctx, refspec, indexDesc, fs.contentStore, remoteStore)
441+
if err != nil {
442+
return nil, fmt.Errorf("%w: error trying to fetch SOCI artifacts: %w", snapshot.ErrNoIndex, err)
443+
}
444+
return index, nil
445+
}
446+
449447
func getIDMappedMountpoint(mountpoint, activeLayerID string) string {
450448
d := filepath.Dir(mountpoint)
451449
return filepath.Join(fmt.Sprintf("%s_%s", d, activeLayerID), "fs")

0 commit comments

Comments
 (0)