AWSでいうとこのS3ですが、OCIでは、オブジェクトストレージっていうんです。
やってることは同じなんですが、値段と種類が違うんですよ。
このオブジェクトストレージは、1Gバイト単位で値段が違っていて、アーカイブというやつが一番安いんです。
じゃー、とりあえずアーカイブで保存すりゃ良いじゃんと思うんですが、デメリットがあるんですね。
そりゃーそうですよ。
アーカイブは、1ファイル単位で設定出来るんですが、一度アーカイブすると、リストアするまで使えなくなります。
しかも、このリストア処理は、最短1時間から、23時間程度はかかるので、すぐに利用しないといけない場合、使えません。
なので、基本バックアップ用だと思って下さい。
で、さらに注意すべきは、一度リストアするとアーカイブすることが出来ません。
なので、一旦、ダウンロードしてから削除、登録といった手順が必要になるのです。
使い方は、OCIのWEB画面から、アップロード、ダウンロードが一番簡単な使い方です。
その他は、OCI CLIといったコマンドや、各言語用のAPIを使ったり、直接REST APIを使ったり出来ます。
最もユーザーよりの使い方は、StorageGatewayを使った、NFSマウントも使えます。
基本的に、S3互換なので、S3FS等を利用することも可能です。
S3FSを使ってマウントし、Sambaで共有してみましたが、普通に使えました。
但し、ブロックストレージとオブジェクトストレージ(標準)の1GB単価が同じなので、ブロックストレージをSamba共有した方が良いかと思います。
そんなオブジェクトストレージですが、アーカイブ、リストアするのが、Webだと めちゃくちゃ面倒です。
なので、一括でアーカイブ、リストアを行うPython3を作成しました。
#!/usr/bin/python3
import os
import sys
import json
import subprocess
import argparse
import re
import tempfile
import shutil
namespace=''
bucketname=''
parser = argparse.ArgumentParser(description='OCI ObjectStorage Archive')
parser.add_argument('namespace',help='Bucket namespace')
parser.add_argument('bucketname',help='Bucket Name')
parser.add_argument('--startmatch',help='Name start match')
parser.add_argument('--match',help='Name reg match')
parser.add_argument('--dryrun', action='store_true', help='Dryrun')
parser.add_argument('--start', help='Start object name')
parser.add_argument('--limit', type=int ,help='Count limit', default=20000)
args = parser.parse_args()
namespace = args.namespace
bucketname = args.bucketname
startmatchstr = args.startmatch
regmatchstr = args.match
dryrun = args.dryrun
startwith = args.start
limitcount = args.limit
optionargs = ''
if( startwith is not None ):
optionargs = '--start {0} '.format(startwith)
objlist = subprocess.check_output('oci os object list --namespace {0} --bucket-name {1} --limit {2} {3}'.format(namespace,bucketname,limitcount,optionargs), encoding='utf-8', shell=True)
dict = json.loads(objlist)
for node in dict['data']:
objname = node['name']
hit = True
#前方一致
if( startmatchstr is not None and objname.startswith(startmatchstr) == False ):
hit = False
#正規表現
if( regmatchstr is not None and re.search(regmatchstr,objname) == None ):
hit = False
if hit == True and node['archival-state']=='Restored' :
print("reupload {0}".format(objname))
if( dryrun == False ):
#リストア済の場合、ダウンロードし、再アップロードの必要がある
temp_dir_path = tempfile.mkdtemp()
purefilename = os.path.basename(objname)
localfilepath = os.path.join(temp_dir_path,purefilename)
os.path.dirname(localfilepath)
result = subprocess.check_output('oci os object get --namespace {0} --bucket-name {1} --name "{2}" --file "{3}" '.format(namespace,bucketname,objname,localfilepath), encoding='utf-8', shell=True)
result = subprocess.check_output('oci os object put --force --namespace {0} --bucket-name {1} --name "{2}" --file "{3}" '.format(namespace,bucketname,objname,localfilepath), encoding='utf-8', shell=True)
shutil.rmtree(temp_dir_path)
if hit == True and (node['archival-state']!='Archived' and node['archival-state']!='Restored' and node['archival-state']!='Restoring' ) :
print( objname)
if( dryrun == False ):
result = subprocess.check_output('oci os object update-storage-tier --namespace {0} --bucket-name {1} --object-name "{2}" --storage-tier "Archive"'.format(namespace,bucketname,objname), encoding='utf-8', shell=True)
print(result)
#!/usr/bin/python3
import os
import sys
import json
import subprocess
import argparse
import re
namespace=''
bucketname=''
parser = argparse.ArgumentParser(description='OCI ObjectStorage Resotre')
parser.add_argument('namespace',help='Bucket namespace')
parser.add_argument('bucketname',help='Bucket Name')
parser.add_argument('--startmatch',help='Name start match')
parser.add_argument('--match',help='Name reg match')
parser.add_argument('--dryrun', action='store_true', help='Dryrun')
parser.add_argument('--start', help='Start object name')
parser.add_argument('--limit', type=int ,help='Count limit', default=20000)
args = parser.parse_args()
namespace = args.namespace
bucketname = args.bucketname
startmatchstr = args.startmatch
regmatchstr = args.match
dryrun = args.dryrun
startwith = args.start
limitcount = args.limit
optionargs = ''
if( startwith is not None ):
optionargs = '--start {0} '.format(startwith)
objlist = subprocess.check_output('oci os object list --namespace {0} --bucket-name {1} --limit {2} {3}'.format(namespace,bucketname,limitcount,optionargs), encoding='utf-8', shell=True)
dict = json.loads(objlist)
for node in dict['data']:
objname = node['name']
hit = True
#前方一致
if( startmatchstr is not None and objname.startswith(startmatchstr) == False ):
hit = False
#正規表現
if( regmatchstr is not None and re.search(regmatchstr,objname) == None ):
hit = False
if hit == True and node['archival-state']=='Archived' :
print( objname)
if( dryrun == False ):
result = subprocess.check_output('oci os object restore --namespace {0} --bucket-name {1} --name "{2}" --hours 1 '.format(namespace,bucketname,objname), encoding='utf-8', shell=True)
print(result)