[Oracle Cloud] curl コマンドで Object Storage へファイル Upload/Download してみてみた

Object Storage 事前認証済リクエスト(Pre-Authenticated Requests: PAR)で作成されるリクエストURLを使用すると、curl などのツールを使用して、事前認証済リクエストを使用してデータの読取りと書込みを行うことができます。
オブジェクト・ストレージでは、[マルチパート・アップロード](https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/usingpreauthenticatedrequests_topic-Working_with_PreAuthenticated_Requests.htm#To_put_a_large_object)と事前認証済リクエストを使用した[大きなファイルの書込み](https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/usingpreauthenticatedrequests_topic-Working_with_PreAuthenticated_Requests.htm#To_put_a_large_object)がサポートされます。
ということで、curl コマンドで、Object Storageへファイルの Upload/Download してみてみます。



# ■ Object Storage 事前認証済リクエスト作成

### 1) Object Storage 画面
対象の Object Storage Bucketを選択し、左ペイン：Resources項目の Pre-Authenticated Requests を選択し、[Create Pre-Authenticated Request]をクリック
![01_PAR01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/30ba0cbd-7a71-8e1d-27af-27d1a4e4d4c6.jpeg)



### 2）Create Pre-Authenticated Request 画面
次の項目を入力し、[reate Pre-Authenticated Request]をクリック

    ・ Name: 事前認証済リクエスト名を入力
    　 　　文字、数字、ダッシュ、アンダースコアおよびピリオドのみを使用
    ・ Pre-Authenticated Request Target: ここでは、[バケット]を選択
    ・ Access Type: ここでは、[オブジェクトの読取りと書込みを許可]を選択
    ・ Enable Object Listing: 事前認証済リクエスト・ユーザーにバケット内のオブジェクトのリストを許可する場合は、このオプションを選択します。
    ・ Expiration: 有効期限を入力。日時エディタを使用して有効期限日時を指定

![01_PAR02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/e0cff005-2142-50c0-7bba-5ff0892a0481.jpeg)



### 3）Pre-Authenticated Request Details画面
リクエストが作成されると、「事前認証済リクエストの詳細」ダイアログ・ボックスに、バケットへのアクセスに使用されるURLが表示されます。
URLの右側にあるコピー・アイコンをクリックし、URLを永続ストレージの任意の場所に貼り付けて、後で参照できるようにします。
![01_PAR03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/89875fb3-1240-ff1b-fa63-5160c9b49e67.jpeg)
```:PAR URL例
https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/
```


事前認証済リクエストを作成する際にシステムによって提供される一意のURLは、ユーザーがリクエスト・ターゲットにアクセスできる唯一の方法です。URLを耐久ストレージにコピーします。URLは作成時のみ表示され、オブジェクト・ストレージに格納されず、後で取得できません。

### 4）作成確認
作成した 事前認証済リクエスト (PAR)の Status が "Active" であることを確認
![01_PAR04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/b55fc34f-c7c7-b577-a7f8-d7b3eea15e71.jpeg)

:::note info
PAR の Expiration (有効期限)が無効になると、Statusは "Expired(失効)" になり使用できなくなります。
![03_PAR失効.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/4b1e4434-d1b0-17e5-ae5a-a7b137ef3f12.jpeg)
:::





# ■ テストファイル作成
OBject Storage へ Upload/Download するテストファイルを作成します。

### ・ 1G ファイル作成
```
[opc@db-inst ~]$ dd if=/dev/zero of=1G-File.txt bs=1024k count=1000

	1000+0 records in
	1000+0 records out
	1048576000 bytes (1.0 GB) copied, 1.93374 s, 542 MB/s
```


### ・ 5G ファイル作成
```
[opc@db-inst ~]$ dd if=/dev/zero of=5G-File.txt bs=1024k count=5000
	5000+0 records in
	5000+0 records out
	5242880000 bytes (5.2 GB) copied, 13.7676 s, 381 MB/s
```

### ・ 10G ファイル作成
```
[opc@db-inst ~]$  dd if=/dev/zero of=10G-File.txt bs=1024k count=10000
	10000+0 records in
	10000+0 records out
	10485760000 bytes (10 GB) copied, 48.3352 s, 217 MB/s
```

### ・ ファイル作成確認
```
[opc@db-inst ~]$ ls -lh
	total 16G
	-rw-rw-r--. 1 opc opc  9.8G Apr  6 12:49 10G-File.txt
	-rw-rw-r--. 1 opc opc  4.9G Apr  6 12:43 5G-File.txt
	-rw-rw-r--. 1 opc opc 1000M Apr  6 12:43 1G-File.txt
```


# ■ Curl で ファイル・アップロード
```:コマンド
curl -X PUT --data-binary '@<ファイル名>' <unique-PAR-URL>/<ファイル名>
```


### 1) アップロード・ファイル確認
```
[opc@db-inst ~]$ ls -lh
	total 2048000
	-rw-r--r--  1 shirok  staff   1.0G Apr  5 23:34 1G-File.txt
```

### 2) ファイル・アップロード

```
[opc@db-inst ~]$ curl -v -X PUT --data-binary '@/Users/shirok/Downloads/test/1G-File.txt' https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/1G-File.txt

	*   Trying 134.70.80.3:443...
	* Connected to objectstorage.ap-tokyo-1.oraclecloud.com (134.70.80.3) port 443 (#0)
	* ALPN, offering h2
	* ALPN, offering http/1.1
	* successfully set certificate verify locations:
	*  CAfile: /etc/ssl/cert.pem
	*  CApath: none
	* (304) (OUT), TLS handshake, Client hello (1):
	* (304) (IN), TLS handshake, Server hello (2):
	* TLSv1.2 (IN), TLS handshake, Certificate (11):
	* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
	* TLSv1.2 (IN), TLS handshake, Server finished (14):
	* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
	* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
	* TLSv1.2 (OUT), TLS handshake, Finished (20):
	* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
	* TLSv1.2 (IN), TLS handshake, Finished (20):
	* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
	* ALPN, server did not agree to a protocol
	* Server certificate:
	*  subject: C=US; ST=California; L=Redwood City; O=Oracle Corporation; CN=objectstorage.ap-tokyo-1.oraclecloud.com
	*  start date: Mar  1 00:00:00 2023 GMT
	*  expire date: Mar 21 23:59:59 2024 GMT
	*  subjectAltName: host "objectstorage.ap-tokyo-1.oraclecloud.com" matched cert's "objectstorage.ap-tokyo-1.oraclecloud.com"
	*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
	*  SSL certificate verify ok.
	> PUT /p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/1G-File.txt HTTP/1.1
	> Host: objectstorage.ap-tokyo-1.oraclecloud.com
	> User-Agent: curl/7.79.1
	> Accept: */*
	> Content-Length: 1048576000
	> Content-Type: application/x-www-form-urlencoded
	> Expect: 100-continue
	>
	* Mark bundle as not supporting multiuse
	< HTTP/1.1 100 Continue

	* We are completely uploaded and fine
	* Mark bundle as not supporting multiuse
	< HTTP/1.1 200 OK
	< etag: ae09672b-b87b-4f9d-b87d-e04894e70ae5
	< last-modified: Wed, 05 Apr 2023 14:38:45 GMT
	< opc-content-md5: 5cg0+9qmv9jqxeuUBO791A==
	< version-id: d6b01c45-483f-4d02-b37c-0a79a0e51c49
	< Content-Length: 0
	< date: Wed, 05 Apr 2023 14:38:45 GMT
	< opc-request-id: nrt-1:YcsawYZRa_dawdgbfpBd8im_Zszi6
	< x-api-id: native
	< access-control-allow-origin: *
	< access-control-allow-methods: POST,PUT,GET,HEAD,DELETE,OPTIONS
	< access-control-allow-credentials: true
	< access-control-expose-headers: access-control-allow-credentials,access-control-allow-methods,access-control-allow-origin,content-length,date,etag,last-modified,opc-client-info,opc-content-md5,opc-request-id,version-id,x-api-id
	<
	* Connection #0 to host objectstorage.ap-tokyo-1.oraclecloud.com left intact
```

### 3) ファイル・アップロード確認
オブジェクトをリストできます。

```:コマンド
$ curl -X GET <unique-PAR-URL>
```

**・実行**
```
[opc@db-inst ~]$ curl -X GET https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/

	{"objects":[{"name":"1G-File.txt"}]}%
```


### ※ エラー出た場合
100 MiBを超えるオブジェクトをアップロードするには、マルチパート・アップロードを使用することをお薦めします。
インターネットの性能に応じて次のようなエラーが出るため、転送できるサイズへファイルを分割してマルチパート・アップロードを使用して転送します。

```:エラー出力例
[opc@db-inst ~]$ curl -X PUT --data-binary '@100G-File.txt' https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/100G-File.txt

curl: option --data-binary: out of memory
curl: try 'curl --help' or 'curl --manual' for more information
```


# ■ Curl で マルチパート・アップロード
マルチパート・アップロードは、単一のアップロード操作に対して大きすぎるオブジェクトに対応します。
100 MiBを超えるオブジェクトをアップロードするには、マルチパート・アップロードを使用することをお薦めします。
アップロードされるオブジェクトの最大サイズは 10 TiB です。オブジェクト・パートは 50 GiB 以下である必要があります。
マルチパート・アップロードを使用すると、個々のパートのアップロード間で一時停止し、スケジュールとリソースが許すときにアップロードを再開する柔軟性が得られます。

### 1)  Split the large file into parts
大きすぎるオブジェクトを splitコマンドで分割します。

```
[opc@db-inst ~]$ split -b 1G -d 5G-File.txt
[opc@db-inst ~]$ ls -lh
	-rw-rw-r--. 1 opc opc  4.9G Apr  6 12:43 5G-File.txt
	-rw-rw-r--. 1 opc opc  1.0G Apr  6 01:42 x00
	-rw-rw-r--. 1 opc opc  1.0G Apr  6 01:42 x01
	-rw-rw-r--. 1 opc opc  1.0G Apr  6 01:42 x02
	-rw-rw-r--. 1 opc opc  1.0G Apr  6 01:42 x03
	-rw-rw-r--. 1 opc opc  904M Apr  6 01:42 x04
```

### 2) マルチパート・アップロードを作成するようにオブジェクト・ストレージに指示
マルチパート・アップロードを作成するようにオブジェクト・ストレージに指示するには、PUTコマンドにヘッダーopc-multipart: trueを含めます。
opc-multipart: trueヘッダーを含むPUTは、パートのアップロードおよびマルチパート・アップロードのコミットに使用するアクセスURIを返します。

```:コマンド
$ curl -X PUT -H "opc-multipart:true" <unique-PAR-URL>
```

**・実行**
```
[opc@tokyo-db-inst01 WORK]$ curl -X PUT -H "opc-multipart:true" https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/5G-File.txt

{"namespace":"shirok","bucket":"OCI-Bucket","object":"5G-File.txt","uploadId":"057e65-5f32-4efc-7dbc","timeCreated":"2023-04-06T01:55:00.445Z","storageTier":"Standard","accessUri":"/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/u/5G-File.txt/id/057e65-5f32-4efc-7dbc/"}
```

### 3) 分割ファイル・アップロード
アクセスURIをターゲット・リージョンのオブジェクト・ストレージ・ホスト名に使用して、URIの最後に部品番号を指定します。
たとえば、オブジェクトを5つのパートでアップロードするには、次のPUTコマンドを発行します。
アクセスURIは、2）で出力れた次の部分になります

```:アクセスURI例
"accessUri":"/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/u/5G-File.txt/id/057e65-5f32-4efc-7dbc/"
```

**・実行**

```
curl -X PUT --data-binary '@x00' https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/u/5G-File.txt/id/057e65-5f32-4efc-7dbc/1
curl -X PUT --data-binary '@x01' https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/u/5G-File.txt/id/057e65-5f32-4efc-7dbc/2
curl -X PUT --data-binary '@x02' https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/u/5G-File.txt/id/057e65-5f32-4efc-7dbc/3
curl -X PUT --data-binary '@x03' https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/u/5G-File.txt/id/057e65-5f32-4efc-7dbc/4
curl -X PUT --data-binary '@x04' https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/u/5G-File.txt/id/057e65-5f32-4efc-7dbc/5
```

:::note info
マルチパート・アップロードを並列で実行するには、バックグラウンド・プロセス等の機能を使用します。
:::
・参考: [Shell Script: 並列実行して処理実行時間を出力してみてみた](https://qiita.com/shirok/items/2dd5cdc5af37c1186671
)

https://qiita.com/shirok/items/2dd5cdc5af37c1186671


### 4) マルチパート・アップロード・コミット
マルチパート・アップロードをコミットするには、アクセスURIを指定してPOSTコマンドを使用します。
```
$ curl -X POST https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/
```

### 5) ファイル・アップロード確認
```
[opc@db-inst ~]$ curl -X GET https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/

	{"objects":[{"name":"5G-File.txt"}]}

```


```:コマンド
$ curl -X DELETE <マルチ・パートURL>
```
:::note info
**失敗した場合の初期化**
アクセスURIを指定してDELETEコマンドを使用して、コミットされていないか失敗したマルチパート・アップロードのすべての部分を削除できます。

```:コマンド
$ curl -X DELETE <マルチ・パートURL>
```
:::


# ■ Curl で ファイル・ダウンロード
```:コマンド
curl -O <unique-PAR-URL>/<ファイル名>
```

### 1) ファイル・ダウンロード
```
curl -O https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/bucket/o/1G-File.txt

	1T4lufDQRUpVi5/n/shirok/b/bucket/o/1G-File.txt

	% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
									Dload  Upload   Total   Spent    Left  Speed
	100    38  100    38    0     0    112      0 --:--:-- --:--:-- --:--:--   114
```

### 2) ファイル・ダウンロード確認
```
[opc@db-inst ~]$ ls -l
	-rw-rw-r--. 1 opc opc  1048576000 Apr  6 12:43 1G-File.txt
```




# ■ Curl で オブジェクトのリストの取得
### 1) オブジェクトのリストの取得
```
[opc@db-inst ~]$ curl -X GET https://objectstorage.ap-tokyo-1.oraclecloud.com/p/Gqte6y5OoWPjEYOzAj-wuHDpy/n/shirok/b/OCI-Bucket/o/

	{"objects":[{"name":"10G-File.txt"},{"name":"1G-File.txt"},{"name":"5G-File.txt"}]}
```

### 2) OCIコンソール確認
![02_Curl-List.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/f0e674fe-89f7-5ccb-805b-426ea8b8a217.jpeg)



# ■ 参考
　・ [Object Storage: 事前認証済リクエストの作業](https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/usingpreauthenticatedrequests_topic-Working_with_PreAuthenticated_Requests.htm)
　・ [オブジェクト・ストレージの事前認証済リクエスト・オブジェクトURL](https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/usingpreauthenticatedrequests_topic-Working_with_PreAuthenticated_Requests.htm)
　・ [split(1) - ユーザーコマンド](https://docs.oracle.com/cd/E19253-01/819-1210/6n3j74jts/index.html)
　・ [Oracle Linux: How to Split Large Files (Doc ID 2371350.1)](https://support.oracle.com/knowledge/Oracle%20Linux%20and%20Virtualization/2371350_1.html)
　・ [curl.com](https://www.curl.com/)