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 }