github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/docs/http_api.md (about) 1 --- 2 layout: post 3 title: RESTFUL API 4 permalink: /docs/http-api 5 redirect_from: 6 - /http_api.md/ 7 - /docs/http_api.md/ 8 --- 9 10 ## Table of Contents 11 12 - [Notation](#notation) 13 - [Overview](#overview) 14 - [Easy URL](#easy-url) 15 - [API Reference](#api-reference) 16 - [Cluster Operations](#cluster-operations) 17 - [Node Operations](#node-operations) 18 - [Mountpaths and Disks](#mountpaths-and-disks) 19 - [Bucket and Object Operations](#bucket-and-object-operations) 20 - [Footnotes](#footnotes) 21 - [Storage Services](#storage-services) 22 - [Multi-Object Operations](#multi-object-operations) 23 - [Working with archives (TAR, TGZ, ZIP, MessagePack)](#working-with-archives-tar-tgz-zip-messagepack) 24 - [Starting, stopping, and querying batch operations (jobs)](#starting-stopping-and-querying-batch-operations-jobs) 25 - [Backend Provider](#backend-provider) 26 - [Curl Examples](#curl-examples) 27 - [Querying information](#querying-information) 28 - [Example: querying runtime statistics](#example-querying-runtime-statistics) 29 - [ETL](#etl) 30 31 ## Notation 32 33 In this README: 34 35 > `G` - denotes a (hostname:port) address of a **gateway** (any gateway in a given AIS cluster) 36 37 > `T` - (hostname:port) of a storage **target** 38 39 > `G-or-T` - (hostname:port) of **any node** member of the cluster 40 41 ## Overview 42 43 AIStore supports a growing number and variety of RESTful operations. To illustrate common conventions, let's take a look at the example: 44 45 ```console 46 $ curl -X GET http://G-or-T/v1/daemon?what=config 47 ``` 48 49 This command queries one of the AIS nodes (denoted as `G-or-T`) for its configuration. The query - as well as most of other control plane queries - results in a JSON-formatted output that can be viewed with any compatible JSON viewer. 50 51 Notice the 6 (six) elements that usually accompany any RESTful operation: 52 53 1. Command line **option** or flag. 54 55 In particular, note the '-X` (or `--request`) and `-L` (`--location`) options that `curl` supports. Those are important. 56 57 Run `curl --help` for help. 58 59 2. **HTTP verb** aka method, one of: `PUT`, `GET`, `HEAD`, `POST`, `DELETE`, or `PATCH`. 60 61 In the example, it's a GET but it can also be POST, PUT, and DELETE. For a brief summary of the standard HTTP verbs and their CRUD semantics, see, for instance, this [REST API tutorial](http://www.restapitutorial.com/lessons/httpmethods.html). 62 63 3. **Hostname** (or IPv4 address) and TCP port of one of the AIStore daemons. 64 65 Most RESTful operations performed on an AIStore proxy/gateway will likely have a *clustered* scope. Exceptions may include querying proxy's own configuration via `?what=config`, and more. 66 67 4. **URL path**: version of the REST API, RESTful *resource* that is operated upon, and possibly more forward-slash delimited specifiers. 68 69 For example: /v1/cluster where `v1` is the currently supported API version and `cluster` is the (RESTful) resource. Other *resources* include (but are **not** limited to): 70 71 | RESTful resource | Description | 72 | --- | ---| 73 | `cluster` | cluster-wide control-plane operation | 74 | `daemon` (aka **node**) | control-plane request to update or query specific AIS daemon (proxy or target). In the documentation, the terms "daemon" and "node" are used interchangeably. | 75 | `buckets` | create, destroy, rename, copy, transform (entire) buckets; list objects in a given bucket; get bucket names for a given provider (or all providers); get bucket properties | 76 | `objects` | datapath request to GET, PUT and DELETE objects, read their properties | 77 | `download` | download external datasets and/or selected files from remote buckets, HDFS, or even specific HTTP locations | 78 | `sort` | user-defined distributed shuffle | 79 80 and more. 81 82 For the most recently updated **URL paths**, please see: 83 84 * [`api/apc/urlpaths.go`](https://github.com/NVIDIA/aistore/blob/main/api/apc/urlpaths.go) 85 86 5. **URL query**, e. g., `?what=config`. 87 88 In particular, all API requests that operate on a bucket carry the bucket's specification details in the URL's query. Those details may include [backend provider](/docs/providers.md) and [namespace](/docs/providers.md#unified-global-namespace) where an empty backend provider indicates an AIS bucket (with AIStore being, effectively, the default provider) while an empty namespace parameter translates as a global (default) namespace. For exact names of the bucket-specifying URL Query parameters, please refer to this [API source](/api/bucket.go). 89 90 > Combined, all these elements tell the following story. They specify the most generic action (e.g., GET) and designate the target aka "resource" of this action: e. g., an entire cluster or a given AIS node. Further, they may also include context-specific and query string encoded control message to, for instance, distinguish between getting system statistics (`?what=stats`) versus system configuration (`?what=config`). 91 92 > For developers and first-time users: if you deployed AIS locally having followed [these instructions](/README.md#local-non-containerized) then most likely you will have `http://localhost:8080` as the primary proxy, and generally, `http://localhost:808x` for all locally-deployed AIS daemons. 93 94 > The reference below is "formulated" in `curl` - i.e., using `curl` command lines. It is possible, however, and often much easier (and, therefore, **preferable**), to execute the same operations using [AIS CLI](/docs/cli.md). 95 96 6. And finally, **HTTP request and response headers** 97 98 All supported query parameters and all HTTP headers are enumerated and commented in the following two sources, respectively: 99 100 * [REST API Query parameters](https://github.com/NVIDIA/aistore/blob/main/api/apc/query.go) 101 * [REST API Headers](https://github.com/NVIDIA/aistore/blob/main/api/apc/headers.go) 102 103 ## Easy URL 104 105 "Easy URL" is a simple alternative mapping of the AIS API to handle URLs paths that look as follows: 106 107 * **GET http(s)://host:port/provider/[bucket[/object]]** 108 * **PUT http(s)://host:port/provider/[bucket[/object]]**, 109 110 The capability enables (convenient) usage of your Internet Browser (or `curl`, etc. tools). In other words, you can use simple intuitive URLs to execute: 111 112 1. GET(object) 113 2. PUT(object) 114 3. list-objects(bucket) 115 4. list-buckets 116 117 **NOTE**: rest of this section provides a short summary; please see [easy URL readme](/docs/easy_url.md) for background, details, and extended comments. 118 119 In other words, the supported URL paths include: 120 121 | URL | Comment | 122 |--- | --- | 123 | `/gs/mybucket/myobject` | read, write, delete, and list objects in Google Cloud buckets | 124 | `/az/mybucket/myobject` | same, for Azure Blob Storage buckets | 125 | `/ais/mybucket/myobject` | AIS buckets | 126 127 ```console 128 # Example: GET 129 $ curl -s -L -X GET 'http://aistore/gs/my-google-bucket/abc-train-0001.tar -o abc-train-0001.tar' 130 131 # Using conventional AIS RESTful API, the same exact GET operation will look as follows: 132 $ curl -s -L -X GET 'http://aistore/v1/objects/my-google-bucket/abc-train-0001.tar?provider=gs -o abc-train-0001.tar' 133 134 # Example: PUT 135 $ curl -s -L -X PUT 'http://aistore/gs/my-google-bucket/abc-train-9999.tar -T /tmp/9999.tar' 136 137 # For comparison, the same without using "easy URL": 138 $ curl -s -L -X PUT 'http://aistore/v1/objects/my-google-bucket/abc-train-9999.tar?provider=gs -T /tmp/9999.tar' 139 140 # Example: LIST (i.e., `list-objects`) 141 $ curl -s -L -X GET 'http://aistore/gs/my-google-bucket' | jq 142 ``` 143 144 > AIS provides S3 compatibility layer via its "/s3" endpoint. [S3 compatibility](/docs/s3compat.md) shall not be confused with "easy URL" mapping, whereby a path (e.g.) "gs/mybucket/myobject" gets replaced with "v1/objects/mybucket/myobject?provider=gcp" with _no_ other changes to the request and response parameters and components. 145 146 > For detals and more usage examples, please see [easy URL readme](/docs/easy_url.md). 147 148 ## API Reference 149 150 The entire AIStore RESTful API is substantial in size. It is also constantly growing, which is why this section is structured as several groups of related APIs. 151 152 In addition, the rightmost column references AIS [api](https://github.com/NVIDIA/aistore/tree/main/api) package and the specific Go-based API in it that performs the same **operation**. Needless to say - simply because we use it ourselves across a variety of Go-based clients and apps, the [api](https://github.com/NVIDIA/aistore/tree/main/api) package will always contain the most recently updated version of the API. 153 154 In other words, AIS [api](https://github.com/NVIDIA/aistore/tree/main/api) is always current and can be used to lookup the most recently updated version of the RESTful API. 155 156 ### Cluster Operations 157 158 This and the next section reference a variety of URL paths (e.g., `/v1/cluster`). For the most recently updated list of all URLs, see: 159 160 * [`api/apc/urlpaths.go`](https://github.com/NVIDIA/aistore/blob/main/api/apc/urlpaths.go) 161 162 | Operation | HTTP action | Example | Go API | 163 |--- | --- | ---|--- | 164 | Add a node to cluster | POST /v1/cluster/join-by-admin | (to be added) | `api.JoinCluster` | 165 | Put node in maintenance (that is, safely and temporarily remove the node from the cluster _upon rebalancing_ the node's data between remaining nodes) | (to be added) | (to be added) | `api.StartMaintenance` | 166 | Take node out of maintenance | (to be added) | (to be added) | `api.StopMaintenance` | 167 | Decommission a node | (to be added) | (to be added) | `api.Decommission` | 168 | Decommission entire cluster | PUT {"action": "decommission"} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "decommission"}' 'http://G-primary/v1/cluster'` | `api.DecommissionCluster` | 169 | Shutdown ais node | PUT {"action": "shutdown-node", "value": {"sid": daemonID}} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "shutdown-node", "value": {"sid": "43888:8083"}}' 'http://G/v1/cluster'` | `api.ShutdownNode` | 170 | Decommission entire cluster | PUT {"action": "decommission"} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "decommission"}' 'http://G-primary/v1/cluster'` | `api.DecommissionCluster` | 171 | Query cluster health | GET /v1/health | See [Probing liveness and readiness](#probing-liveness-and-readiness) section below | `api.Health` | 172 | Set primary proxy | PUT /v1/cluster/proxy/new primary-proxy-id | `curl -i -X PUT 'http://G-primary/v1/cluster/proxy/26869:8080'` | `api.SetPrimaryProxy` | 173 | Force-Set primary proxy (NOTE: advanced usage only!) | PUT /v1/daemon/proxy/proxyID | `curl -i -X PUT -G 'http://G-primary/v1/daemon/proxy/23ef189ed' --data-urlencode "frc=true" --data-urlencode "can=http://G-new-designated-primary"` <sup id="a6">[6](#ft6)</sup>| `api.SetPrimaryProxy` | 174 | Get cluster configuration | GET /v1/cluster | See [Querying information](#querying-information) section below | `api.GetClusterConfig` | 175 | Get `BMD` ("bucket metadata") | GET /v1/cluster or GET /v1/daemon | See [Querying information](#querying-information) section below | `api.GetBMD` | 176 | Set cluster-wide configuration **via JSON message** (proxy) | PUT {"action": "set-config", "name": "some-name", "value": "other-value"} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "set-config","name": "stats_time", "value": "1s"}' 'http://G/v1/cluster'`<br>• Note below the alternative way to update cluster configuration<br>• For the list of named options, see [runtime configuration](/docs/configuration.md) | `api.SetClusterConfigUsingMsg` | 177 | Set cluster-wide configuration **via URL query** | PUT /v1/cluster/set-config/?name1=value1&name2=value2&... | `curl -i -X PUT 'http://G/v1/cluster/set-config?stats_time=33s&log.loglevel=4'`<br>• Allows to update multiple values in one shot<br>• For the list of named configuration options, see [runtime configuration](/docs/configuration.md) | `api.SetClusterConfig` | 178 | Reset cluster-wide configuration | PUT {"action": "reset-config"} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "reset-config"}' 'http://G/v1/cluster'` | `api.ResetClusterConfig` | 179 | Shutdown cluster | PUT {"action": "shutdown"} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "shutdown"}' 'http://G-primary/v1/cluster'` | `api.ShutdownCluster` | 180 | Rebalance cluster | PUT {"action": "start", "value": {"kind": "rebalance"}} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "start", "value": {"kind": "rebalance"}}' 'http://G/v1/cluster'` | `api.StartXaction` | 181 | Resilver cluster | PUT {"action": "start", "value": {"kind": "resilver"}} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "start", "value": {"kind": "resilver"}}' 'http://G/v1/cluster'` | `api.StartXaction` | 182 | Abort global (automated or manually started) rebalance (proxy) | PUT {"action": "stop", "value": {"kind": "rebalance"}} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "stop", "value": {"kind": "rebalance"}}' 'http://G/v1/cluster'` | | 183 | Remove storage target from the cluster (NOTE: advanced usage only - use Maintenance API instead!) | DELETE /v1/cluster/daemon/daemonID | `curl -i -X DELETE 'http://G/v1/cluster/daemon/15205:8083'` | n/a | 184 | Join storage target (NOTE: advanced usage only - use JoinCluster API instead!)| POST /v1/cluster/register | `curl -i -X POST -H 'Content-Type: application/json' -d '{"daemon_type": "target", "node_ip_addr": "172.16.175.41", "daemon_port": "8083", "direct_url": "http://172.16.175.41:8083"}' 'http://localhost:8083/v1/cluster/register'` | n/a | 185 | Join proxy (aka "gateway") | POST /v1/cluster/register | `curl -i -X POST -H 'Content-Type: application/json' -d '{"daemon_type": "proxy", "node_ip_addr": "172.16.175.41", "daemon_port": "8083", "direct_url": "http://172.16.175.41:8083"}' 'http://localhost:8083/v1/cluster/register'` | n/a | 186 | Get Cluster Map | (to be added) | See [Querying information](#querying-information) section below | `api.GetClusterMap` | 187 | Get Cluster Map from a specific node (any node in the cluster) | See [Querying information](#querying-information) section below | (to be added) | `api.GetNodeClusterMap` | 188 | Get Cluster System information | GET /v1/cluster | See [Querying information](#querying-information) section below | `api.GetClusterSysInfo` | 189 | Get Cluster statistics | GET /v1/cluster | See [Querying information](#querying-information) section below | `api.GetClusterStats` | 190 | Get remote AIS-cluster information (access URL, primary gateway, cluster map version, and more) | GET /v1/cluster | See [Querying information](#querying-information) section below | `api.GetRemoteAIS` | 191 | Attach remote AIS cluster | PUT /v1/cluster/attach | (to be added) | `api.AttachRemoteAIS` | 192 | Detach remote AIS cluster | PUT /v1/cluster/detach | (to be added) | `api.DetachRemoteAIS` | 193 194 ### Node Operations 195 196 The operations that are limited in scope to a single specified node and that usually require node ID: 197 198 | Operation | HTTP action | Example | Go API | 199 |--- | --- | ---|--- | 200 | Get node log | GET /v1/daemon | See [Querying information](#querying-information) section below | `api.GetDaemonLog` | 201 | Resilver storage target | PUT {"action": "start", "value": {"kind": "resilver", "node": targetID}} /v1/cluster | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "start", "value": {"kind": "resilver", "node": "43888:8083"}}' 'http://G/v1/cluster'` | `api.StartXaction` | 202 | Get target IO (aka disk) statistics | (to be added) | (to be added) | `api.GetTargetDiskStats` | 203 | Get node log | (to be added) | (to be added) | `api.GetDaemonLog` | 204 | Get node status | (to be added) | (to be added) | `api.GetDaemonStatus` | 205 | Get node config | (to be added) | (to be added) | `api.GetDaemonConfig` | 206 | Set node configuration | PUT /v1/daemon/set-config/?name1=value1&name2=value2&... | `curl -i -X PUT 'http://G-or-T/v1/daemon/set-config?stats_time=33s&log.loglevel=4'`<br>• Allows to update multiple values in one shot<br>• For the list of named configuration options, see [runtime configuration](/docs/configuration.md) | `api.SetDaemonConfig` | 207 | Reset node configuration | PUT {"action": "reset-config"} /v1/daemon | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "reset-config"}' 'http://G-or-T/v1/daemon'` | `api.ResetDaemonConfig` | 208 | Get target IO (aka disk) statistics | (to be added) | (to be added) | `api.GetTargetDiskStats` | 209 | Set (i.e., update) node config | (to be added) | (to be added) | `api.SetDaemonConfig` | 210 | Reset AIS node configuration | PUT {"action": "reset-config"} /v1/daemon | `curl -i -X PUT -H 'Content-Type: application/json' -d '{"action": "reset-config"}' 'http://G-or-T/v1/daemon'` | `api.ResetDaemonConfig` | 211 212 ### Probing liveness and readiness 213 214 In this section, two quick `curl` examples. Notice response headers that show both the cluster and the responding node's respective uptimes (in nanoseconds): 215 216 ```console 217 $ curl -i http://localhost:8080//v1/health 218 HTTP/1.1 200 OK 219 Ais-Cluster-Uptime: 295433144686 220 Ais-Node-Uptime: 310453738871 221 Date: Tue, 08 Nov 2022 14:11:57 GMT 222 Content-Length: 0 223 ``` 224 225 And here's a health probe executed during cluster startup: 226 227 ```console 228 $ curl -i http://localhost:8080//v1/health?prr=true 229 HTTP/1.1 503 Service Unavailable 230 Ais-Cluster-Uptime: 5578879646 231 Ais-Node-Uptime: 20603416072 232 Content-Type: application/json 233 X-Content-Type-Options: nosniff 234 Date: Tue, 08 Nov 2022 14:17:59 GMT 235 Content-Length: 221 236 237 {"message":"p[lgGp8080] primary is not ready yet to start rebalance (started=true, starting-up=true)","method":"GET","url_path":"//v1/health","remote_addr":"127.0.0.1:42720","caller":"","node":"p[lgGp8080]","status":503} 238 ``` 239 240 An additional query parameter `prr=true` requests (an additional) check whether the cluster is ready to rebalance itself upon any *membership changes*. 241 242 Unless cluster rebalancing was previously interrupted, there's usually a few seconds interval of time between the following two events: 243 244 * ready to run traffic 245 * ready to run traffic and, simultaneously, globally rebalance if new nodes join (or existing nodes leave) the cluster 246 247 To the (fully expected) question of where the `prr` query comes from - all supported query parameters and all HTTP headers are enumerated and commented in the following two sources: 248 249 * [REST API Query parameters](https://github.com/NVIDIA/aistore/blob/main/api/apc/query.go) 250 * [REST API Headers](https://github.com/NVIDIA/aistore/blob/main/api/apc/headers.go) 251 252 ### Mountpaths and Disks 253 254 Special subset of node operations (see previous section) to manage disks attached to specific storage target. The corresponding AIS abstraction is called [mountpath](/docs/overview.md#terminology). 255 256 These APIs also require specific node ID (to identify the target in the cluster to operate on): 257 258 | Operation | HTTP action | Example | Go API | 259 |--- | --- | ---|--- | 260 | Get target's mountpath info | (to be added) | (to be added) | `api.GetMountpaths` | 261 | Attach mountpath | (to be added) | (to be added) | `api.AddMountpath` | 262 | Remove mountpath | (to be added) | (to be added) | `api.RemoveMountpath` | 263 | Enable mountpath | (to be added) | (to be added) | `api.EnableMountpath` | 264 | Disable mountpath | (to be added) | (to be added) | `api.DisableMountpath` | 265 266 ### Bucket and Object Operations 267 268 Many of the operations on buckets and objects support numerous options. Not all of these options are listed in the table below; in fact, the table may serve as a quick summary but may also lag behind the latest released version of AIStore. 269 270 Thirdly, some of the operations are further documented in separate sections below, including: 271 272 * [Listing buckets](#listing-buckets) 273 * [Listing objects](#listing-objects) 274 275 and more. 276 277 | Operation | HTTP action | Example | Go API | 278 |--- | --- | ---|--- | 279 | List buckets aka `list-buckets` (not to confuse with `list-objects` below) | GET {"action": "list"} /v1/buckets/ | `curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list"}' 'http://G/v1/buckets/'`. More examples in the section [Listing buckets](#listing-buckets) below | `api.ListBuckets` | 280 | Create [bucket](/docs/bucket.md) | POST {"action": "create-bck"} /v1/buckets/bucket-name | `curl -i -X POST -H 'Content-Type: application/json' -d '{"action": "create-bck"}' 'http://G/v1/buckets/abc'` | `api.CreateBucket` | 281 | Destroy [bucket](/docs/bucket.md) | DELETE {"action": "destroy-bck"} /v1/buckets/bucket-name | `curl -i -X DELETE -H 'Content-Type: application/json' -d '{"action": "destroy-bck"}' 'http://G/v1/buckets/abc'` | `api.DestroyBucket` | 282 | Rename ais [bucket](/docs/bucket.md) | POST {"action": "move-bck"} /v1/buckets/from-name | `curl -i -X POST -H 'Content-Type: application/json' -d '{"action": "move-bck" }' 'http://G/v1/buckets/from-name?bck=<bck>&bckto=<to-bck>'` | `api.RenameBucket` | 283 | Copy [bucket](/docs/bucket.md) | POST {"action": "copy-bck"} /v1/buckets/from-name | `curl -i -X POST -H 'Content-Type: application/json' -d '{"action": "copy-bck", }}}' 'http://G/v1/buckets/from-name?bck=<bck>&bckto=<to-bck>'` | `api.CopyBucket` | 284 | Rename/move object (ais buckets only) | POST {"action": "rename", "name": new-name} /v1/objects/bucket-name/object-name | `curl -i -X POST -L -H 'Content-Type: application/json' -d '{"action": "rename", "name": "dir2/DDDDDD"}' 'http://G/v1/objects/mybucket/dir1/CCCCCC'` <sup id="a3">[3](#ft3)</sup> | `api.RenameObject` | 285 | Check if an object from a remote bucket *is present* | HEAD /v1/objects/bucket-name/object-name | `curl -s -L --head 'http://G/v1/objects/mybucket/myobject?check_cached=true'` | `api.HeadObject` | 286 | GET object | GET /v1/objects/bucket-name/object-name | `curl -s -L -X GET 'http://G/v1/objects/myS3bucket/myobject?provider=s3' -o myobject` <sup id="a1">[1](#ft1)</sup> | `api.GetObject`, `api.GetObjectWithValidation`, `api.GetObjectReader`, `api.GetObjectWithResp` | 287 | Read range | GET /v1/objects/bucket-name/object-name | `curl -s -L -X GET -H 'Range: bytes=1024-1535' 'http://G/v1/objects/myS3bucket/myobject?provider=s3' -o myobject`<br> Note: For more information about the HTTP Range header, see [this](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35) | `` | 288 | List objects (`list-objects`) in a given [bucket](/docs/bucket.md) | GET {"action": "list", "value": { properties-and-options... }} /v1/buckets/bucket-name | `curl -X GET -L -H 'Content-Type: application/json' -d '{"action": "list", "value":{"props": "size"}}' 'http://G/v1/buckets/myS3bucket'` <sup id="a2">[2](#ft2)</sup> | `api.ListObjects` (see also `api.ListObjectsPage` and section [Listing objects](#listing-objects) below | 289 | Get [bucket properties](/docs/bucket.md#bucket-properties) | HEAD /v1/buckets/bucket-name | `curl -s -L --head 'http://G/v1/buckets/mybucket'` | `api.HeadBucket` | 290 | Get object props | HEAD /v1/objects/bucket-name/object-name | `curl -s -L --head 'http://G/v1/objects/mybucket/myobject'` | `api.HeadObject` | 291 | Set object's custom (user-defined) properties | (to be added) | (to be added) | `api.SetObjectCustomProps` | 292 | PUT object | PUT /v1/objects/bucket-name/object-name | `curl -s -L -X PUT 'http://G/v1/objects/myS3bucket/myobject' -T filenameToUpload` | `api.PutObject` | 293 | APPEND to object | PUT /v1/objects/bucket-name/object-name?appendty=append&handle= | `curl -s -L -X PUT 'http://G/v1/objects/myS3bucket/myobject?appendty=append&handle=' -T filenameToUpload-partN` <sup>[8](#ft8)</sup> | `api.AppendObject` | 294 | Finalize APPEND | PUT /v1/objects/bucket-name/object-name?appendty=flush&handle=obj-handle | `curl -s -L -X PUT 'http://G/v1/objects/myS3bucket/myobject?appendty=flush&handle=obj-handle'` <sup>[8](#ft8)</sup> | `api.FlushObject` | 295 | Delete object | DELETE /v1/objects/bucket-name/object-name | `curl -i -X DELETE -L 'http://G/v1/objects/mybucket/myobject'` | `api.DeleteObject` | 296 | Set [bucket properties](/docs/bucket.md#bucket-properties) (proxy) | PATCH {"action": "set-bprops"} /v1/buckets/bucket-name | `curl -i -X PATCH -H 'Content-Type: application/json' -d '{"action":"set-bprops", "value": {"checksum": {"type": "sha256"}, "mirror": {"enable": true}, "force": false}' 'http://G/v1/buckets/abc'` <sup id="a9">[9](#ft9)</sup> | `api.SetBucketProps` | 297 | Reset [bucket properties](/docs/bucket.md#bucket-properties) (proxy) | PATCH {"action": "reset-bprops"} /v1/buckets/bucket-name | `curl -i -X PATCH -H 'Content-Type: application/json' -d '{"action":"reset-bprops"}' 'http://G/v1/buckets/abc'` | `api.ResetBucketProps` | 298 | [Evict](/docs/bucket.md#prefetchevict-objects) object | DELETE '{"action": "evict-listrange"}' /v1/objects/bucket-name/object-name | `curl -i -X DELETE -L -H 'Content-Type: application/json' -d '{"action": "evict-listrange"}' 'http://G/v1/objects/mybucket/myobject'` | `api.EvictObject` | 299 | [Evict](/docs/bucket.md#evict-bucket) remote bucket | DELETE {"action": "evict-remote-bck"} /v1/buckets/bucket-name | `curl -i -X DELETE -H 'Content-Type: application/json' -d '{"action": "evict-remote-bck"}' 'http://G/v1/buckets/myS3bucket'` | `api.EvictRemoteBucket` | 300 | Promote file or directory | POST {"action": "promote", "name": "/home/user/dirname", "value": {"target": "234ed78", "recurs": true, "keep": true}} /v1/buckets/bucket-name | `curl -i -X POST -H 'Content-Type: application/json' -d '{"action":"promote", "name":"/user/dir", "value": {"target": "234ed78", "trim_prefix": "/user/", "recurs": true, "keep": true} }' 'http://G/v1/buckets/abc'` <sup>[7](#ft7)</sup>| `api.PromoteFileOrDir` | 301 302 ### Listing buckets 303 304 #### Example 1. List all buckets in the [global namespace](/docs/providers.md): 305 306 ```console 307 $ curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list"}' 'http://localhost:8080/v1/buckets' | jq 308 [ 309 { 310 "name": "abc", 311 "provider": "ais", 312 "namespace": { 313 "uuid": "", 314 "name": "" 315 } 316 }, 317 "name": "jonh-s3-bucket", 318 "provider": "aws", 319 "namespace": { 320 "uuid": "", 321 "name": "" 322 } 323 }, 324 { 325 "name": "my-gs-bucket", 326 "provider": "gcp", 327 "namespace": { 328 "uuid": "", 329 "name": "" 330 } 331 }, 332 ... 333 ] 334 ``` 335 336 #### Example 2. List only those buckets in the global namespace that are **present** in the cluster: 337 338 ```console 339 $ curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list"}' 'http://localhost:8080/v1/buckets?presence=2' | jq 340 [ 341 { 342 "name": "abc", 343 "provider": "ais", 344 "namespace": { 345 "uuid": "", 346 "name": "" 347 } 348 } 349 { 350 "name": "my-gs-bucket", 351 "provider": "gcp", 352 "namespace": { 353 "uuid": "", 354 "name": "" 355 } 356 }, 357 ] 358 359 ``` 360 361 The `presence=` query parameter tells AIStore to look only for the buckets that are **present** in the AIS bucket metadata called `BMD`. 362 363 Remote buckets (such as, for instance, `s3://jonh-s3-bucket` above) may not be present but they will still be fully accessible - both readable and writeable, assuming, of course, that the cluster is provided with right credentials. 364 365 > That's because AIS supports on-the-fly bucket creation. When user references a new bucket, AIS looks it up behind the scenes, confirms its existence and accessibility, and updates its own cluster-wide global metadata that contains bucket definitions, associated management policies, and properties. 366 367 Further, all supported query parameters are enumerated and commented in the following source: 368 369 * [REST API Query parameters](https://github.com/NVIDIA/aistore/blob/main/api/apc/query.go) 370 371 #### Examples 3.1 and 3.2. Listing buckets in remote namespaces 372 373 In the two examples below, we list buckets in the remote AIS cluster that we have previously [attached](/docs/providers.md#remote-ais-cluster) (which is not shown here). We have attached it and called `remais`. 374 375 In other words, `remais` in this example is, simultaneously, a user-given name to reference remote AIS cluster, and a namespace for this cluster's buckets - all of them. 376 377 ```console 378 # 3.1. List remote ais://@remais/... buckets that are present in our cluster: 379 380 $ curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list"}' 'http://localhost:8080/v1/buckets?provider=ais&namespace=@remais&presence=2' | jq 381 [ 382 { 383 "name": "abc", 384 "provider": "ais", 385 "namespace": { 386 "uuid": "ihGdxzrC3", 387 "name": "" 388 } 389 } 390 ] 391 392 The result (above) translates as `ais://@remais/abc` or - same - `ais://@ihGdxzrC3/abc`. 393 394 This is the only bucket from the remote AIS cluster with UUID "ihGdxzrC3" that we currently have in our cluster. 395 396 # 3.2. List all remote ais://@remais/... buckets: 397 398 $ curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list"}' 'http://localhost:8080/v1/buckets?provider=ais&namespace=@remais' | jq 399 [ 400 { 401 "name": "abc", 402 "provider": "ais", 403 "namespace": { 404 "uuid": "remais", 405 "name": "" 406 } 407 }, 408 { 409 "name": "xyz", 410 "provider": "ais", 411 "namespace": { 412 "uuid": "remais", 413 "name": "" 414 } 415 } 416 ] 417 ``` 418 419 The results include two remote buckets: `ais://@remais/abc` and `ais://@remais/xyz`. 420 421 And again, to read, write and otherwise reference these buckets we could (in this case) use `@remais` and `@ihGdxzrC3` interchangeably. 422 423 ### Listing objects 424 425 #### Example 1. List `ais://abc` and use all defaults for the numerous supported (listing) options: 426 427 ```console 428 $ curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list"}' 'http://localhost:8080/v1/buckets/abc?provider=ais' | jq 429 { 430 "uuid": "J-6ynHbFVx", 431 "continuation_token": "", 432 "entries": [ 433 { 434 "name": "LICENSE", 435 "checksum": "ed5b3e74f9f3516a", 436 "atime": "09 Nov 22 18:52 EST", 437 "size": "1075", 438 "flags": 64 439 } 440 ], 441 "flags": 0 442 } 443 ``` 444 445 As far as "numerous supported options", JSON message '{"action": "list"}' in the `curl` command line translates as: 446 447 ```console 448 { 449 "action": "list", 450 "value": { 451 "props": "name, size", 452 "start_after":"", 453 "pagesize": 0, 454 "flags": "0", 455 "uuid": "", 456 "time_format ":"", 457 "prefix": "", 458 "continuation_token":"", 459 "target": "", 460 }, 461 } 462 ``` 463 464 Each of these value fields - "props", "flags", etc. - has its own utility. For closely related reference, see e.g.: 465 466 * [CLI to list objects](/docs/cli/bucket.md#list-objects) 467 468 #### Example 2. Same as above using alternative [easy URL](#easy-url) notation: 469 470 ```console 471 $ curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list"}' 'http://localhost:8080/ais/abc' | jq 472 ``` 473 474 #### Example 3. Compare the following two `curl` commands that look almost identical but produce different results. 475 476 But first, let's do this: 477 478 ```console 479 $ ais put LICENSE gs://nv 480 $ ais object evict gs://nv/LICENSE 481 ``` 482 483 And now, use `curl` to list objects in a Cloud bucket called `gs://nv`: 484 485 ```console 486 # 3.1. List only those objects that are _present_ or (same) cached in the cluster: 487 488 $ curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list", "value": {"flags": "1"}}' 'http://localhost:8080/gs/nv' | jq 489 { 490 "uuid": "P0CeeasVj", 491 "continuation_token": "", 492 "entries": null, 493 "flags": 0 494 } 495 496 # 3.2. List _all_ objects: 497 $ curl -s -L -X GET -H 'Content-Type: application/json' -d '{"action": "list", "value": {"flags": "0"}}' 'http://localhost:8080/gs/nv' | jq 498 { 499 "uuid": "Tk0eebFnx", 500 "continuation_token": "", 501 "entries": [ 502 { 503 "name": "LICENSE", 504 "checksum": "f70a21a0c5fa26a93820b0bef5be7619", 505 "version": "1668040083889738", 506 "size": "1075" 507 } 508 ], 509 "flags": 0 510 } 511 ``` 512 513 ### Storage Services 514 515 | Operation | HTTP action | Example | Go API | 516 |--- | --- | ---|--- | 517 | Erasure code entire bucket | (to be added) | (to be added) | `api.ECEncodeBucket` | 518 | Configure bucket as [n-way mirror](/docs/storage_svcs.md#n-way-mirror) | POST {"action": "make-n-copies", "value": n} /v1/buckets/bucket-name | `curl -i -X POST -H 'Content-Type: application/json' -d '{"action":"make-n-copies", "value": 2}' 'http://G/v1/buckets/abc'` | `api.MakeNCopies` | 519 | Enable [erasure coding](/docs/storage_svcs.md#erasure-coding) protection for all objects (proxy) | POST {"action": "ec-encode"} /v1/buckets/bucket-name | `curl -i -X POST -H 'Content-Type: application/json' -d '{"action":"ec-encode"}' 'http://G/v1/buckets/abc'` | (to be added) | 520 521 ### Multi-Object Operations 522 523 | Operation | HTTP action | Example | Go API | 524 |--- | --- | ---|--- | 525 | [Prefetch](/docs/bucket.md#prefetchevict-objects) a list of objects | POST '{"action":"prefetch", "value":{"objnames":"[o1[,o]]"}}' /v1/buckets/bucket-name | `curl -i -X POST -H 'Content-Type: application/json' -d '{"action":"prefetch", "value":{"objnames":["o1","o2","o3"]}}' 'http://G/v1/buckets/abc'` <sup>[4](#ft4)</sup> | `api.PrefetchList` | 526 | [Prefetch](/docs/bucket.md#prefetchevict-objects) a range of objects| POST '{"action":"prefetch", "value":{"template":"your-prefix{min..max}" }}' /v1/buckets/bucket-name | `curl -i -X POST -H 'Content-Type: application/json' -d '{"action":"prefetch", "value":{"template":"__tst/test-{1000..2000}"}}' 'http://G/v1/buckets/abc'` <sup>[4](#ft4)</sup> | `api.PrefetchRange` | 527 | Delete a list of objects | DELETE '{"action":"delete", "value":{"objnames":"[o1[,o]]"}}' /v1/buckets/bucket-name | `curl -i -X DELETE -H 'Content-Type: application/json' -d '{"action":"delete", "value":{"objnames":["o1","o2","o3"]}}' 'http://G/v1/buckets/abc'` <sup>[4](#ft4)</sup> | `api.DeleteList` | 528 | Delete a range of objects | DELETE '{"action":"delete", "value":{"template":"your-prefix{min..max}"}}' /v1/buckets/bucket-name | `curl -i -X DELETE -H 'Content-Type: application/json' -d '{"action":"delete", "value":{"template":"__tst/test-{1000..2000}"}}' 'http://G/v1/buckets/abc'` <sup>[4](#ft4)</sup> | `api.DeleteRange` | 529 | | (to be added) | (to be added) | | 530 | [Evict](/docs/bucket.md#prefetchevict-objects) a list of objects | DELETE '{"action":"evictobj", "value":{"objnames":"[o1[,o]]"}}' /v1/buckets/bucket-name | `curl -i -X DELETE -H 'Content-Type: application/json' -d '{"action":"evictobj", "value":{"objnames":["o1","o2","o3"]}}' 'http://G/v1/buckets/abc'` <sup>[4](#ft4)</sup> | `api.EvictList` | 531 | [Evict](/docs/bucket.md#prefetchevict-objects) a range of objects| DELETE '{"action":"evictobj", "value":{"template":"your-prefix{min..max}"}}' /v1/buckets/bucket-name | `curl -i -X DELETE -H 'Content-Type: application/json' -d '{"action":"evictobj", "value":{"template":"__tst/test-{1000..2000}"}}' 'http://G/v1/buckets/abc'` <sup>[4](#ft4)</sup> | `api.EvictRange` | 532 | Copy multiple objects from bucket to bucket | (to be added) | (to be added) | `api.CopyMultiObj` | 533 | Copy and, simultaneously, transform multiple objects (i.e., perform user-defined offline transformation) | (to be added) | (to be added) | `api.ETLMultiObj` | 534 535 ### Working with archives (TAR, TGZ, ZIP, [MessagePack](https://msgpack.org)) 536 537 | Operation | HTTP action | Example | Go API | 538 |--- | --- | ---|--- | 539 | Create multi-object archive _or_ append multiple objects to an existing one | (to be added) | (to be added) | `api.CreateArchMultiObj` | 540 | APPEND to an existing archive | (to be added) | (to be added) | `api.AppendToArch` | 541 | List archived content | (to be added) | (to be added) | `api.ListObjects` and friends | 542 543 ### Starting, stopping, and querying batch operations (jobs) 544 545 The term we use in the code and elsewhere is [xaction](/docs/overview.md#terminology) - a shortcut for *eXtended action*. For definition and further references, see: 546 547 * [Terminology](/docs/overview.md#terminology) 548 * [Batch operations](/docs/batch.md) 549 550 | Operation | HTTP action | Example | Go API | 551 |--- | --- | ---|--- | 552 | Start xaction | (to be added) | (to be added) | `api.StartXaction` | 553 | Abort xaction | (to be added) | (to be added) | `api.AbortXaction` | 554 | Get xaction stats by ID | (to be added) | (to be added) | `api.GetXactionStatsByID` | 555 | Query xaction stats | (to be added) | (to be added) | `api.QueryXactionStats` | 556 | Get xaction status | (to be added) | (to be added) | `api.GetXactionStatus` | 557 | Wait for xaction to finish | (to be added) | (to be added) | `api.WaitForXaction` | 558 | Wait for xaction to become idle | (to be added) | (to be added) | `api.WaitForXactionIdle` | 559 560 ## Backend Provider 561 562 Any storage bucket that AIS handles may originate in a 3rd party Cloud, or in another AIS cluster, or - the 3rd option - be created (and subsequently filled-in) in the AIS itself. But what if there's a pair of buckets, a Cloud-based and, separately, an AIS bucket that happen to share the same name? To resolve all potential naming, and (arguably, more importantly) partition namespace with respect to both physical isolation and QoS, AIS introduces the concept of *provider*. 563 564 * [Backend Provider](/docs/providers.md) - an abstraction, and simultaneously an API-supported option, that allows to delineate between "remote" and "local" buckets with respect to a given AIS cluster. 565 566 > Backend provider is realized as an optional parameter across all AIStore APIs that handle access to user data and bucket configuration. The list (of those APIs) includes GET, PUT, DELETE and [Range/List](/docs/batch.md) operations. For supported backend providers, please refer to [backend providers](/docs/providers.md) and/or [Buckets: introduction and detailed overview](/docs/bucket.md) documents. 567 568 For even more information, CLI examples, and the most recent updates, please see: 569 - [Backend Providers](/docs/providers.md) 570 - [CLI: operations on buckets](/docs/cli/bucket.md) 571 - [CLI: operations on objects](/docs/cli/object.md) 572 - [On-Disk Layout](/docs/on_disk_layout.md) 573 574 ## Curl Examples 575 576 ```console 577 # List a given AWS bucket 578 $ curl -s -L -X GET 'http://G/v1/objects/myS3bucket/myobject?provider=aws' 579 580 # Using locally deployed AIS, get archived file from a remote named tar: 581 $ curl -s -L -X GET 'http://localhost:8080/v1/objects/myGCPbucket/train-1234.tar?provider=gcp&archpath=567.jpg' --output /tmp/567.jpg 582 % Total % Received % Xferd Average Speed Time Time Time Current 583 Dload Upload Total Spent Left Speed 584 100 201 100 201 0 0 196k 0 --:--:-- --:--:-- --:--:-- 196k 585 100 44327 100 44327 0 0 2404k 0 --:--:-- --:--:-- --:--:-- 2404k 586 $ file /tmp/567.jpg 587 /tmp/567.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 294x312, frames 3 588 ``` 589 590 And here's another (somewhat more involved) example that ties an existing AIS bucket `ais://nnn` to a remote backend called (in this case) `gs://cloud_bucket`: 591 592 ```console 593 $ curl -i -X PATCH -H 'Content-Type: application/json' -d '{"action":"set-bprops", "value": {"backend_bck":{"name":"cloud_bucket", "provider":"gcp"}}}' 'http://G/v1/buckets/nnn' 594 HTTP/1.1 200 OK 595 Date: Thu, 21 Jul 2022 17:42:47 GMT 596 Content-Length: 0 597 598 # Next, we PUT directly into gs://cloud_bucket and then check the result via ais://nnn 599 $ ais ls gs://cloud_bucket -H | wc -l 600 0 601 $ ais put README.md gs://cloud_bucket 602 PUT "README.md" to gcp://cloud_bucket 603 604 $ ais ls ais://nnn 605 NAME SIZE 606 README.md 9.97KiB 607 608 # List with Google version and checksum: 609 $ ais ls ais://nnn --props name,size,checksum,version 610 NAME SIZE CHECKSUM VERSION 611 README.md 9.97KiB a56d5e9f313480b7bbe41256012fb7b0 1658425395717602 612 ``` 613 614 ## Querying information 615 616 A typical query is a GET request that includes `?what=<...>` (HTTP) query. For the most recently updated `what=` enumeration, see: 617 618 * [REST API Query parameters](https://github.com/NVIDIA/aistore/blob/main/api/apc/query.go) 619 620 Notice that many cluster-level operations can be designated to both the entire cluster or any specific node. For instance, for the current cluster map we can use `GET /v1/cluster?what=smap` and `GET /v1/daemon?what=smap`. This is because each node in the cluster would have a replica (of the map), and it also may be useful to find out the current cluster map of the node that's joining right now, and so on. 621 622 Querying statistics would be another typical example whereby `GET /v1/daemon?what=stats` reports runtime stats of a specific node, while `GET /v1/cluster?what=stats` returns a combined JSON table that includes all of the above. 623 624 Table-summary follows below but first, let's look at examples. 625 626 For instance, if we want to show all remote clusters [attached](/docs/providers.md#remote-ais-cluster) to our cluster, we do something like: 627 628 ```console 629 $ curl -s -L http://localhost:8080//v1/cluster?what=remote | jq 630 { 631 "a": [ 632 { 633 "url": "http://127.0.0.1:11080", 634 "alias": "remais", 635 "uuid": "cKEuiUYz-l", 636 "smap": { 637 "pmap": { 638 "Cifp11080": { 639 "public_net": { 640 "node_ip_addr": "127.0.0.1", 641 "daemon_port": "11080", 642 "direct_url": "http://127.0.0.1:11080" 643 }, 644 ... 645 ... 646 "daemon_type": "target", 647 "daemon_id": "pWWt11081", 648 "flags": 0 649 } 650 }, 651 "uuid": "cKEuiUYz-l", 652 "creation_time": "2022-11-08 09:07:08.009409455 -0500 EST m=+16.021127017", 653 "version": "14" 654 } 655 } 656 ], 657 "ver": 3 658 ``` 659 660 The result in this case includes the cluster's URL, alias, UUID and Smap - for each remote cluster. 661 662 Another useful query could be retrieving log information from any selected node (notice `/daemon` in the URL path): 663 664 ```console 665 curl -s -L -i http://localhost:8081//v1/daemon?what=log | less 666 667 HTTP/1.1 200 OK 668 Date: Tue, 08 Nov 2022 17:03:03 GMT 669 Content-Type: text/plain; charset=utf-8 670 Transfer-Encoding: chunked 671 672 Started up at 2023/11/08 02:34:35, host ais-target-13, go1.21.4 for linux/amd64 673 W 02:34:35.701629 config:1238 control and data share one intra-cluster network (ais-target-13.ais.svc.cluster.local) 674 I 02:34:35.701785 config:1755 log.dir: "/var/log/ais"; l4.proto: tcp; pub port: 51081; verbosity: 3 675 I 02:34:35.701791 config:1757 config: "/etc/ais/.ais.conf"; stats_time: 10s; authentication: false; backends: [aws] 676 I 02:34:35.701811 daemon:195 Version 3.21.1.4ce0e0b, build time 2023-11-08T00:05:16+0000, debug false, CPUs(256, runtime=256), containerized 677 I 02:34:35.702060 init:42 Checking (HOSTNAME: "ais-target-13") 678 I 02:34:35.721086 init:60 K8s spec: NodeName 10.0.140.13 Hostname ais-target-13 HostNetwork false 679 680 ... 681 I 02:34:54.772574 htrun:1916 t[DfooZbarT] via primary health: cluster startup Ok, Smap v34[t=10, p=10] 682 ... 683 ``` 684 685 This (log observing operation) could be especially handy for (low-level) troubleshooting of any kind. Just another tool to use. 686 687 Following is a brief summary of the majority of supported monitoring operations that query the current state and status of both the entire cluster (via `/cluster` URL) or any given node (via `/daemon`). 688 689 | Query <what> | HTTP action | Example | 690 |--- | --- | ---| 691 | Cluster map | GET /v1/cluster | `curl -X GET http://G/v1/cluster?what=smap` | 692 | Cluster map | GET /v1/daemon | `curl -X GET http://G/v1/daemon?what=smap` | 693 | Node configuration| GET /v1/daemon | `curl -X GET http://G-or-T/v1/daemon?what=config` | 694 | Remote clusters | GET /v1/cluster | `curl -X GET http://G-or-T/v1/cluster?what=remote` | 695 | Node information | GET /v1/daemon | `curl -X GET http://G-or-T/v1/daemon?what=snode` | 696 | Node status | GET /v1/daemon | `curl -X GET http://G-or-T/v1/daemon?what=status` | 697 | Cluster statistics (proxy) | GET /v1/cluster | `curl -X GET http://G/v1/cluster?what=stats` | 698 | Node statistics | GET /v1/daemon | `curl -X GET http://T/v1/daemon?what=stats` | 699 | System info for all nodes in cluster | GET /v1/cluster | `curl -X GET http://G/v1/cluster?what=sysinfo` | 700 | Node system info | GET /v1/daemon | `curl -X GET http://G-or-T/v1/daemon?what=sysinfo` | 701 | Node log | GET /v1/daemon | `curl -X GET http://G-or-T/v1/daemon?what=log` | 702 | Get xactions' statistics (proxy) [More](/xact/README.md)| GET /v1/cluster | `curl -i -X GET -H 'Content-Type: application/json' -d '{"action": "stats", "name": "xactionname", "value":{"bucket":"bckname"}}' 'http://G/v1/cluster?what=xaction'` | 703 | List of target's filesystems | GET /v1/daemon?what=mountpaths | `curl -X GET http://T/v1/daemon?what=mountpaths` | 704 | List of all target filesystems | GET /v1/cluster?what=mountpaths | `curl -X GET http://G/v1/cluster?what=mountpaths` | 705 | Comma-separated list of IPs of all targets (compare with `?what=snode` above) | GET /v1/cluster | `curl -X GET http://G/v1/cluster?what=target_ips` | 706 | `BMD` (bucket metadata) | GET /v1/daemon | `curl -X GET http://T/v1/daemon?what=bmd` | 707 708 ### Example: querying runtime statistics 709 710 ```console 711 $ curl -X GET http://G/v1/cluster?what=stats 712 ``` 713 714 Execution flow for this single command causes intra-cluster broadcast whereby requesting proxy (which could be any proxy in the cluster) consolidates all results from all other nodes in a JSON-formatted output. The latter contains both http proxy and storage targets request counters, per-target used/available capacities, and more. For example: 715 716 ![AIStore statistics](images/ais-get-stats.png) 717 718 More usage examples can be found in the [README that describes AIS configuration](/docs/configuration.md). 719 720 ## ETL 721 722 For API Reference of ETL please refer to [ETL Readme](/docs/etl.md#api-reference) 723 724 ## Footnotes 725 726 <a name="ft1">1</a>) This will fetch the object "myS3object" from the bucket "myS3bucket". Notice the -L - this option must be used in all AIStore supported commands that read or write data - usually via the URL path /v1/objects/. For more on the -L and other useful options, see [Everything curl: HTTP redirect](https://ec.haxx.se/http-redirects.html). [↩](#a1) 727 728 <a name="ft2">2</a>) See the [List Objects section](/docs/bucket.md#list-objects) for details. [↩](#a2) 729 730 <a name="ft3">3</a>) Notice the -L option here and elsewhere. [↩](#a3) 731 732 <a name="ft4">4</a>) See the [List/Range Operations section](/docs/batch.md#listrange-operations) for details. 733 734 <a name="ft5">5</a>) The request returns an HTTP status code 204 if the mountpath is already enabled/disabled or 404 if mountpath was not found. [↩](#a5) 735 736 <a name="ft6">6</a>) Advanced usage only. Use it to reassign the primary *role* administratively or if a cluster ever gets in a so-called [split-brain mode](https://en.wikipedia.org/wiki/Split-brain_(computing)). [↩](#a6) 737 738 <a name="ft7">7</a>) The request promotes files to objects; note that the files must be present inside AIStore targets and be referenceable via local directories or fully qualified names. The example request promotes recursively all files of a directory `/user/dir` that is on the target with ID `234ed78` to objects of a bucket `abc`. As `trim_prefix` is set, the names of objects are the file paths with the base trimmed: `dir/file1`, `dir/file2`, `dir/subdir/file3` etc. [↩](#a7) 739 740 <a name="ft8">8</a>) When putting the first part of an object, `handle` value must be empty string or omitted. On success, the first request returns an object handle. The subsequent `AppendObject` and `FlushObject` requests must pass the handle to the API calls. The object gets accessible and appears in a bucket only after `FlushObject` is done. 741 742 <a name="ft9">9</a>) Use option `"force": true` to ignore non-critical errors. E.g, to modify `ec.objsize_limit` when EC is already enabled, or to enable EC if the number of target is less than `ec.data_slices + ec.parity_slices + 1`. [↩](#a9)