github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/api/apc/lsmsg.go (about)

     1  // Package apc: API control messages and constants
     2  /*
     3   * Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved.
     4   */
     5  package apc
     6  
     7  import (
     8  	"net/http"
     9  	"strings"
    10  
    11  	"github.com/NVIDIA/aistore/cmn/cos"
    12  )
    13  
    14  const (
    15  	LocationPropSepa = ":"
    16  	LsPropsSepa      = ","
    17  )
    18  
    19  // LsoMsg flags
    20  const (
    21  	// Applies to objects from the buckets with remote backends (e.g., to optimize-out listing remotes)
    22  	// See related Flt* enum
    23  	LsObjCached = 1 << iota
    24  
    25  	LsMissing // include missing main obj (with copy existing)
    26  
    27  	LsDeleted // include obj-s marked for deletion (TODO: not implemented yet)
    28  
    29  	LsArchDir // expand archives as directories
    30  
    31  	LsNameOnly // return only object names and, spearately, statuses
    32  	LsNameSize // same as above and size (minor speedup)
    33  
    34  	// Background: ============================================================
    35  	// as far as AIS is concerned, adding a (confirmed to exist)
    36  	// remote bucket (and its properties) to the cluster metadata is equivalent
    37  	// to creating the bucket on the fly. =====================================
    38  
    39  	// same as fltPresence == apc.Present (see query.go)
    40  	LsBckPresent
    41  
    42  	// LsDontHeadRemote is introduced primarily to support GCP buckets with
    43  	// ACL policies that allow public _anonymous_ access.
    44  	//
    45  	// It appears that sometimes those policies do honor HEAD(bucket),
    46  	// while other times they don't, failing the request with 401 or 403 status.
    47  	// See also:
    48  	// * https://cloud.google.com/storage/docs/access-control/making-data-public
    49  	// * cmd/cli/cli/const.go for `dontHeadRemoteFlag`
    50  	// * `QparamDontHeadRemote` (this package)
    51  	LsDontHeadRemote
    52  
    53  	// To list remote buckets without adding them to aistore
    54  	// See also:
    55  	// * cmd/cli/cli/const.go for `dontAddRemoteFlag`
    56  	// * `QparamDontAddRemote` (this package)
    57  	LsDontAddRemote
    58  
    59  	// cache list-objects results and use this cache to speed-up
    60  	UseListObjsCache
    61  
    62  	// For remote buckets - list only remote props (aka `wantOnlyRemote`). When false,
    63  	// the default that's being used is: `WantOnlyRemoteProps` - see below.
    64  	// When true, the request gets executed in a pass-through fashion whereby a single ais target
    65  	// simply forwards it to the associated remote backend and delivers the results as is to the
    66  	// requesting proxy and, subsequently, to client.
    67  	LsWantOnlyRemoteProps
    68  
    69  	// List objects without recursion (POSIX-wise).
    70  	// See related feature flag: feat.DontOptimizeVirtualDir
    71  	LsNoRecursion
    72  
    73  	// For remote metadata-capable buckets (ie., bck.HasVersioningMD() == true):
    74  	// - check whether remote version exists,
    75  	// and if it does:
    76  	// - check whether remote version differs from its in-cluster copy
    77  	LsVerChanged
    78  )
    79  
    80  // max page sizes
    81  // see also:  bprops Extra.AWS.MaxPageSize
    82  const (
    83  	MaxPageSizeAIS   = 10000
    84  	MaxPageSizeAWS   = 1000
    85  	MaxPageSizeGCP   = 1000
    86  	MaxPageSizeAzure = 5000
    87  )
    88  
    89  const (
    90  	// Status
    91  	LocOK = iota
    92  	LocMisplacedNode
    93  	LocMisplacedMountpath
    94  	LocIsCopy
    95  	LocIsCopyMissingObj
    96  
    97  	// LsoEntry Flags
    98  	EntryIsCached   = 1 << (EntryStatusBits + 1)
    99  	EntryInArch     = 1 << (EntryStatusBits + 2)
   100  	EntryIsDir      = 1 << (EntryStatusBits + 3)
   101  	EntryIsArchive  = 1 << (EntryStatusBits + 4)
   102  	EntryVerChanged = 1 << (EntryStatusBits + 5) // see also: QparamLatestVer, et al.
   103  	EntryVerRemoved = 1 << (EntryStatusBits + 6) // ditto
   104  )
   105  
   106  // ObjEntry.Flags field
   107  const (
   108  	EntryStatusBits = 5                          // N bits
   109  	EntryStatusMask = (1 << EntryStatusBits) - 1 // mask for N low bits
   110  )
   111  
   112  // LsoMsg and HEAD(object) enum (NOTE: compare with `cmn.ObjectProps`)
   113  const (
   114  	GetPropsName     = "name"
   115  	GetPropsSize     = "size"
   116  	GetPropsVersion  = "version"
   117  	GetPropsChecksum = "checksum"
   118  	GetPropsAtime    = "atime"
   119  	GetPropsCached   = "cached"
   120  	GetPropsStatus   = "status"
   121  	GetPropsCopies   = "copies"
   122  	GetPropsEC       = "ec"
   123  	GetPropsCustom   = "custom"
   124  	GetPropsLocation = "location" // advanced usage
   125  )
   126  
   127  const GetPropsNameSize = GetPropsName + LsPropsSepa + GetPropsSize
   128  
   129  // NOTE: update when changing any of the above :NOTE
   130  var (
   131  	GetPropsMinimal      = []string{GetPropsName, GetPropsSize, GetPropsCached}
   132  	GetPropsDefaultCloud = []string{GetPropsName, GetPropsSize, GetPropsCached,
   133  		GetPropsChecksum, GetPropsVersion, GetPropsCustom}
   134  
   135  	GetPropsDefaultAIS = []string{GetPropsName, GetPropsSize, GetPropsChecksum, GetPropsAtime}
   136  	GetPropsAll        = []string{GetPropsName, GetPropsSize, GetPropsChecksum, GetPropsAtime,
   137  		GetPropsVersion, GetPropsCached, GetPropsStatus, GetPropsCopies, GetPropsEC, GetPropsCustom, GetPropsLocation}
   138  )
   139  
   140  type LsoMsg struct {
   141  	UUID              string      `json:"uuid"`                  // ID to identify a single multi-page request
   142  	Props             string      `json:"props"`                 // comma-delimited, e.g. "checksum,size,custom" (see GetProps* enum)
   143  	TimeFormat        string      `json:"time_format,omitempty"` // RFC822 is the default
   144  	Prefix            string      `json:"prefix"`                // return obj names starting with prefix (TODO: e.g. "A.tar/tutorials/")
   145  	StartAfter        string      `json:"start_after,omitempty"` // start listing after (AIS buckets only)
   146  	ContinuationToken string      `json:"continuation_token"`    // => LsoResult.ContinuationToken => LsoMsg.ContinuationToken
   147  	SID               string      `json:"target"`                // selected target to solely execute backend.list-objects
   148  	Flags             uint64      `json:"flags,string"`          // enum {LsObjCached, ...} - "LsoMsg flags" above
   149  	PageSize          int64       `json:"pagesize"`              // max entries returned by list objects call
   150  	Header            http.Header `json:"hdr,omitempty"`         // (for pointers, see `ListArgs` in api/ls.go)
   151  }
   152  
   153  ////////////
   154  // LsoMsg //
   155  ////////////
   156  
   157  func (lsmsg *LsoMsg) WantOnlyRemoteProps() bool {
   158  	// set by user
   159  	if lsmsg.IsFlagSet(LsWantOnlyRemoteProps) {
   160  		return true
   161  	}
   162  	// set by user or proxy
   163  	if lsmsg.IsFlagSet(LsNameOnly) || lsmsg.IsFlagSet(LsNameSize) {
   164  		return true
   165  	}
   166  	// return false if there's anything outside GetPropsDefaultCloud subset
   167  	for _, wn := range GetPropsAll {
   168  		if lsmsg.WantProp(wn) {
   169  			for _, n := range GetPropsDefaultCloud {
   170  				if wn != n {
   171  					return false
   172  				}
   173  			}
   174  		}
   175  	}
   176  	return true
   177  }
   178  
   179  // WantProp returns true if msg request requires to return propName property.
   180  func (lsmsg *LsoMsg) WantProp(propName string) bool {
   181  	return strings.Contains(lsmsg.Props, propName)
   182  }
   183  
   184  func (lsmsg *LsoMsg) AddProps(propNames ...string) {
   185  	for _, propName := range propNames {
   186  		if lsmsg.WantProp(propName) {
   187  			continue
   188  		}
   189  		if lsmsg.Props != "" {
   190  			lsmsg.Props += LsPropsSepa
   191  		}
   192  		lsmsg.Props += propName
   193  	}
   194  }
   195  
   196  func (lsmsg *LsoMsg) PropsSet() (s cos.StrSet) {
   197  	props := strings.Split(lsmsg.Props, LsPropsSepa)
   198  	s = make(cos.StrSet, len(props))
   199  	for _, p := range props {
   200  		s.Set(p)
   201  	}
   202  	return s
   203  }
   204  
   205  // LsoMsg flags enum: LsObjCached, ...
   206  func (lsmsg *LsoMsg) SetFlag(flag uint64)         { lsmsg.Flags |= flag }
   207  func (lsmsg *LsoMsg) ClearFlag(flag uint64)       { lsmsg.Flags &= ^flag }
   208  func (lsmsg *LsoMsg) IsFlagSet(flags uint64) bool { return lsmsg.Flags&flags == flags }
   209  
   210  func (lsmsg *LsoMsg) Clone() *LsoMsg {
   211  	c := &LsoMsg{}
   212  	cos.CopyStruct(c, lsmsg)
   213  	return c
   214  }