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)