github.com/mgoltzsche/ctnr@v0.7.1-alpha/pkg/fs/fsnodeattrsmap.go (about)

     1  package fs
     2  
     3  import (
     4  	"github.com/golang/protobuf/proto"
     5  	"github.com/mgoltzsche/ctnr/pkg/idutils"
     6  	"github.com/openSUSE/umoci/pkg/rootlesscontainers-proto"
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  type AttrMapper interface {
    11  	ToContainer(a *FileAttrs) error
    12  	ToHost(a *FileAttrs) error
    13  }
    14  
    15  // An AttrMapper that maps uids/gids using rootlesscontainers xattr.
    16  // See https://github.com/rootless-containers/proto
    17  // and https://github.com/openSUSE/umoci/blob/master/oci/layer/utils.go
    18  type rootlessAttrMapper struct {
    19  	idMap idutils.IdMappings
    20  }
    21  
    22  func NewRootlessAttrMapper(idMap idutils.IdMappings) AttrMapper {
    23  	return &rootlessAttrMapper{idMap}
    24  }
    25  
    26  func (s rootlessAttrMapper) ToContainer(a *FileAttrs) (err error) {
    27  	if a.Xattrs != nil {
    28  		if xattrUser, ok := a.Xattrs[rootlesscontainers.Keyname]; ok {
    29  			a.UserIds = idutils.UserIds{}
    30  			var usr rootlesscontainers.Resource
    31  			if err = proto.Unmarshal([]byte(xattrUser), &usr); err != nil {
    32  				return errors.Wrap(err, "uid/gid from xattr "+rootlesscontainers.Keyname)
    33  			}
    34  			if uid := usr.GetUid(); uid != rootlesscontainers.NoopID {
    35  				a.UserIds.Uid = uint(uid)
    36  			}
    37  			if gid := usr.GetGid(); gid != rootlesscontainers.NoopID {
    38  				a.UserIds.Gid = uint(gid)
    39  			}
    40  			delete(a.Xattrs, rootlesscontainers.Keyname)
    41  			return
    42  		}
    43  	}
    44  	a.UserIds = idutils.UserIds{0, 0}
    45  	return
    46  }
    47  
    48  func (s rootlessAttrMapper) ToHost(a *FileAttrs) (err error) {
    49  	usr := rootlesscontainers.Resource{rootlesscontainers.NoopID, rootlesscontainers.NoopID}
    50  	if uid := a.Uid; uid != 0 {
    51  		usr.Uid = uint32(a.Uid)
    52  	}
    53  	if gid := a.Gid; gid != 0 {
    54  		usr.Gid = uint32(a.Gid)
    55  	}
    56  	if !rootlesscontainers.IsDefault(usr) {
    57  		var xattrVal []byte
    58  		if xattrVal, err = proto.Marshal(&usr); err != nil {
    59  			return errors.Wrap(err, "uid/gid to xattr "+rootlesscontainers.Keyname)
    60  		}
    61  		if a.Xattrs == nil {
    62  			a.Xattrs = map[string]string{}
    63  		}
    64  		a.Xattrs[rootlesscontainers.Keyname] = string(xattrVal)
    65  	}
    66  	usrIds := idutils.UserIds{0, 0}
    67  	a.UserIds, err = usrIds.ToHost(s.idMap)
    68  	return
    69  }
    70  
    71  type rootAttrMapper struct {
    72  	idMap idutils.IdMappings
    73  }
    74  
    75  func NewAttrMapper(idMap idutils.IdMappings) AttrMapper {
    76  	return &rootAttrMapper{idMap}
    77  }
    78  
    79  func (s *rootAttrMapper) ToContainer(a *FileAttrs) (err error) {
    80  	a.UserIds, err = a.UserIds.ToContainer(s.idMap)
    81  	return
    82  }
    83  
    84  func (s *rootAttrMapper) ToHost(a *FileAttrs) (err error) {
    85  	a.UserIds, err = a.UserIds.ToHost(s.idMap)
    86  	return nil
    87  }