Copy Sessionの削除
Copy Sessionを削除するスクリプトを記載します。
Copy SessionはDELETE /copysession/{copysession_id} APIでも削除できますが、非同期ConsistencyモードのREC Sessionは削除できません。ここでは、Copy種別を判定し、非同期Consistencyモードの場合はREC Sessionをサスペンドしてから強制削除する処理を自動的に行うスクリプトを記載します。
このスクリプトで削除可能なCopy Sessionの種別は、OPC、QuickOPC、SnapOPC、SnapOPC+、EC、およびRECです。
Copy Sessionの強制削除を実施する場合は、DELETE /copysession/{copysession_id} APIを使用してください。
Copy Session削除時の留意事項は、DELETE /copysession/{copysession_id} APIのCommand Referenceを参照してください。
スクリプトの処理の流れは以下です。
GET /copysession/{copysession_id} APIを使用して削除対象のCopy Session情報を取得する。
削除対象のCopy Sessionが非同期Consistency ModeのREC Sessionだった場合、POST/ copysession/{copysessoin_id}/suspend APIを使用してCopy SessionをSuspendし、未転送データをミラーVolumeに転送する。
削除対象のCopy Sessionが非同期Consistency ModeのREC Sessionだった場合、データの転送完了後にDELETE /copysession/{copysession_id} APIを使用し、Copy Sessionを強制削除する。
削除対象のCopy Sessionが非同期Consistency ModeのREC Session以外だった場合、DELETE /copysession/{copysession_id} APIを使用し、Copy Sessionを削除する。
copysession_delete.py
import sys
import time
from eternus_rest import EtdxBaseApi
# Change the following values for your environment.
storage1_url = "https://192.168.0.1:5665"
storage1_user_name = "username"
storage1_password = "password"
# Copy session ID to delete.
storage1_copysession_id = 1
class EtdxApi(EtdxBaseApi):
def __init__(self, base_url, boxid=None, proxies=None):
super().__init__(base_url, boxid=boxid, proxies=proxies)
def copysession_suspend(self, copysession_id, force=False):
"""Suspend copy session
Args:
copysession_id (int): Copy session ID to suspend.
force (bool, optional): True if force action is required.
Defaults to False.
Returns:
bool: True if successful, False otherwise.
"""
if force:
r = super().post("/api/v1/copysession/{0!s}/suspend?force=true"
.format(copysession_id))
else:
r = super().post("/api/v1/copysession/{0!s}/suspend"
.format(copysession_id))
if r.status_code != 202:
print("Failed to request the copy session suspend.")
print(r)
print(r.json())
return False
# Wait for the job completion
job_r = super().wait_job(r.json()["job_id"])
if job_r.json()["status"] != "Success":
print("Failed to suspend the copy session.")
print(job_r)
print(job_r.json())
return False
return True
def copysession_delete(self, copysession_id, force=False):
"""Delete copy session
Args:
copysession_id (int): Copy session ID to delete
force (bool, optional): True if force action is required.
Defaults to False.
Returns:
bool: True if successful, False otherwise.
"""
if force:
r = super().delete("/api/v1/copysession/{0!s}?force=true"
.format(copysession_id))
else:
r = super().delete("/api/v1/copysession/{0!s}"
.format(copysession_id))
if r.status_code != 202:
print("Failed to request the copy session deletion.")
print(r)
print(r.json())
return False
# Wait for the job completion
job_r = super().wait_job(r.json()["job_id"])
if job_r.json()["status"] != "Success":
print("Failed to delete the copy session.")
print(job_r)
print(job_r.json())
return False
return True
def rec_consistency_wait_for_suspend(self, copysession_id):
"""Wait for the REC concurrent copy session to suspend.
Args:
copysession_id (int): Copy session ID to suspend.
Returns:
bool: True if suspend the copy session is completed.
False if error occurs.
"""
while True:
r = super().get("/api/v1/copysession/{0!s}".format(copysession_id))
data = r.json()
if r.status_code != 200:
print("Failed to get information of the copy session.")
print(r)
print(data)
return False
if data["status"] == "Error":
print("The copy session is in error status.")
print(data)
return False
if data["status"] != "Suspended":
print("Failed to suspend the copy session. Stop access to "
"the source volume of the copy session and try again.")
print(data)
return False
if data["concurrent_suspend_result"] == "Error":
print("Failed to suspend the copy session.")
print(data)
return False
if (data["concurrent_suspend_result"] == "Success"
and data["status"] == "Suspended"):
break
# Get it again after remain_time_to_finish_suspend.
if data["remain_time_to_finish_suspend"] > 10:
time.sleep(data["remain_time_to_finish_suspend"])
else:
time.sleep(10)
return True
def rec_consistency_suspend(self, copysession_id):
"""Suspend the REC consistency session
Args:
copysession_id (int): Copy session ID to suspend.
Returns:
bool: True if suspend the copy session is completed.
False if error occurs.
"""
# Execute suspend if the copy session is not suspended.
r = super().get("/api/v1/copysession/{0!s}".format(copysession_id))
data = r.json()
if r.status_code != 200:
print("Failed to get information of the copy session.")
print(r)
print(data)
return False
if data["status"] != "Suspended":
# Suspend copy session
if not self.copysession_suspend(copysession_id):
return False
# Wait for completion of suspend
if not self.rec_consistency_wait_for_suspend(copysession_id):
print("Some error occurred before suspend completion"
" of the copy session.")
return False
return True
def main():
storage = EtdxApi(storage1_url)
# Login
if not storage.login(storage1_user_name, storage1_password):
return False
print("Deleting the copy session (ID: {0!s})."
.format(storage1_copysession_id))
# Change the delete process according to the copy type.
r = storage.get("/api/v1/copysession/{0!s}"
.format(storage1_copysession_id))
data = r.json()
if r.status_code != 200:
print("Failed to get information of the copy session.")
print(r)
print(data)
return False
# In the case of REC Consistency, deletion is available after
# the completion of the copy session suspend.
if data["type"] == "REC" and data["transfer_mode"] == "Consistency":
print("Suspending the copy session.")
if not storage.rec_consistency_suspend(storage1_copysession_id):
return False
print("Deleting the copy session.")
if not storage.copysession_delete(storage1_copysession_id, force=True):
return False
# Otherwise
else:
print("Deleting the copy session.")
if not storage.copysession_delete(storage1_copysession_id):
return False
print("Succeeded in deleting the copy session.")
# Logout
storage.logout()
return True
if __name__ == '__main__':
if not main():
sys.exit(1)

