github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/util/fs/layout/session.go (about)

     1  // Copyright (c) 2018, Sylabs Inc. All rights reserved.
     2  // This software is licensed under a 3-clause BSD license. Please consult the
     3  // LICENSE.md file distributed with the sources of this project regarding your
     4  // rights to use or distribute this software.
     5  
     6  package layout
     7  
     8  import (
     9  	"fmt"
    10  	"syscall"
    11  
    12  	"github.com/sylabs/singularity/internal/pkg/util/fs/mount"
    13  )
    14  
    15  const rootFsDir = "/rootfs"
    16  const finalDir = "/final"
    17  
    18  // Session directory layout manager
    19  type Session struct {
    20  	*Manager
    21  	Layer layer
    22  }
    23  
    24  // Layer describes a layer interface added on top of session layout
    25  type layer interface {
    26  	Add(*Session, *mount.System) error
    27  }
    28  
    29  // NewSession creates and returns a session directory layout manager
    30  func NewSession(path string, fstype string, size int, system *mount.System, layer layer) (*Session, error) {
    31  	manager := &Manager{}
    32  	session := &Session{Manager: manager}
    33  
    34  	if err := manager.SetRootPath(path); err != nil {
    35  		return nil, err
    36  	}
    37  	if err := manager.AddDir(rootFsDir); err != nil {
    38  		return nil, err
    39  	}
    40  	if err := manager.AddDir(finalDir); err != nil {
    41  		return nil, err
    42  	}
    43  	options := "mode=1777"
    44  	if size > 0 {
    45  		options = fmt.Sprintf("mode=1777,size=%dm", size)
    46  	}
    47  	err := system.Points.AddFS(mount.SessionTag, path, fstype, syscall.MS_NOSUID, options)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	if err := system.RunAfterTag(mount.SessionTag, session.createLayout); err != nil {
    52  		return nil, err
    53  	}
    54  	if layer != nil {
    55  		if err := layer.Add(session, system); err != nil {
    56  			return nil, fmt.Errorf("failed to init layer: %s", err)
    57  		}
    58  		session.Layer = layer
    59  	}
    60  	return session, nil
    61  }
    62  
    63  // Path returns the full path of session directory
    64  func (s *Session) Path() string {
    65  	path, _ := s.GetPath("/")
    66  	return path
    67  }
    68  
    69  // FinalPath returns the full path to session final directory
    70  func (s *Session) FinalPath() string {
    71  	if s.Layer != nil {
    72  		path, _ := s.GetPath(finalDir)
    73  		return path
    74  	}
    75  	return s.RootFsPath()
    76  }
    77  
    78  // RootFsPath returns the full path to session rootfs directory
    79  func (s *Session) RootFsPath() string {
    80  	path, _ := s.GetPath(rootFsDir)
    81  	return path
    82  }
    83  
    84  func (s *Session) createLayout(system *mount.System) error {
    85  	return s.Create()
    86  }