Restarting Data Transfer to a Remote Storage System Backup Volume
The following is a script to resume data transfer to the remote storage system after the end of operation (after completing access to business volumes). This script is used in the operation of periodically backing up the business volume on the remote storage system using REC in asynchronous stack mode and QuickOPC. For more information, see the description of Creating Backups to Remote Storage Systems Using REC and QuickOPC.
The sequence of script processing is as follows.
Restart the REC Session using POST /copysession/{copysession_id}/resume API.
rec_stack_after_operation.py
import sys
from eternus_rest import EtdxBaseApi
# ### Change the following values for your environment. ###
# Source storage (storage that has the source volume)
storage1_url = "https://192.168.0.1:5665"
storage1_user_name = "username"
storage1_password = "password"
# Target storage (storage that has the destination volume)
storage2_url = "https://192.168.0.2:5665"
storage2_user_name = "username"
storage2_password = "password"
# This case is for a REC(Stack) session from the volume on storage1 to
# storage2.
# The destination volume of REC has been cloned using QuickOPC on storage2.
# You can paste the outputs of rec_stack_create.
# REC session ID on storage1 created by the script rec_stack_create.
storage1_copysession_id = 1
# If you want to schedule this script, you can use cron as follows.
# Examples: It is scheduled to execute this post-processing daily at 20:00.
# To ensure data consistency, host access must be stopped before execution.
# crontab -e
# 0 20 * * * python3 /root/rec_stack_after_operation.py >> /root/cron.log 2>&1
class EtdxApi(EtdxBaseApi):
def __init__(self, base_url, boxid=None, proxies=None):
"""Constructor of EtdxApi
If storage is used as target storage of REC without calling login
method in this script, need to specify the boxid of this storage as
follows.
storage2 = EtdxApi(storage2_url,
boxid="00ETERNUSDXHS3ET00000A####EI000001######")
Args:
base_url ([type]): [description]
boxid ([type], optional): [description]. Defaults to None.
proxies ([type], optional): [description]. Defaults to None.
"""
super().__init__(base_url, boxid=boxid, proxies=proxies)
def login(self, user_name="", password=""):
"""Create a session of RESTful API and get boxid.
Args:
user_name (str, optional): User name to login. Defaults to "".
password (str, optional): Password for the user. Defaults to "".
Returns:
bool: True if successful, False otherwise.
"""
rtn = super().login(user_name, password)
if rtn and self.boxid is None:
r = super().get("/api/v1/storagesystem")
if r.status_code != 200:
print(r)
print(r.json())
print("Failed to get boxid.")
return False
self.boxid = r.json()["boxid"]
return rtn
def rec_resume(self, copysession_id):
"""Resume REC session
Args:
copysession_id (int): Copy session ID to resume
Returns:
bool: True if successful, False otherwise.
"""
r = super().post("/api/v1/copysession/{0!s}/resume"
.format(copysession_id))
if r.status_code != 202:
print("Failed to request the REC session resume.")
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 resume the REC session.")
print(job_r)
print(job_r.json())
return False
return True
def main():
storage1 = EtdxApi(storage1_url)
# Login
if not storage1.login(storage1_user_name, storage1_password):
return False
print("Start Post-processing.")
# Post-processing (Execute on storage1)
# REC Resume
print("Resuming the REC session (ID: {0!s})."
.format(storage1_copysession_id))
if not storage1.rec_resume(storage1_copysession_id):
return False
print("REC session resumed.")
print("Post-processing completed.")
# Logout
storage1.logout()
return True
if __name__ == '__main__':
if not main():
sys.exit(1)

