Deleting a Copy Session
The following shows a script that removes the Copy Session.
The Copy Session can also be deleted on the DELETE /copysession/{copysession_id} API, but this API cannot be used to delete a REC Session in asynchronous consistency mode. Here is a script that determines the Copy type and automatically suspends the REC Session and then forces the deletion in asynchronous consistency mode.
The types of Copy Sessions that can be removed with this script are OPC, QuickOPC, SnapOPC, SnapOPC+, EC, and REC.
Use DELETE /copysession/{copysession_id} API to force a removal of a Copy Session.
See the DELETE /copysession/{copysession_id} API Command Reference for considerations when removing a Copy Session.
The sequence of script processing is as follows.
Use GET /copysession/{copysession_id} API to get the Copy Session information to remove.
If the copy session being removed was an REC Session in asynchronous consistency mode, suspend the copy session using POST/ copysession/{copysessoin_id}/suspend API and transfer the untransferred data to the mirror volume.
If the copy session being removed was an REC session in asynchronous consistency mode, use DELETE /copysession/{copysession_id} API after the data transfer is complete to force the removal of the copy session.
If the copy session being removed is not a REC Session in asynchronous consistency mode, use DELETE /copysession/{copysession_id} API to remove the 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)

