Rotating Snapshot
Here is a script that deletes the oldest Snapshot and creates a new one (rotates Snapshots). Use this script for operations that use SnapOPC+ to back up generation-managed differential data. For more information, see the description of Generation Managed Differential Data Backup with SnapOPC+.
You can run this script at any interval, such as with a crontab, to obtain snapshots on a regular basis.
During script execution, to ensure the integrity of Snapshot data, operations volume I/O and applications must be stopped momentarily to create a quiescent point. After the script is complete, the logical copy of the update data is complete and business can resume.
The sequence of script processing is as follows.
Use POST /volume/{volume_id}/snapshot/rotate API to rotate Snapshots.
snapopcplus_rotate.py
import sys
from eternus_rest import EtdxBaseApi
# Change the following values for your environment.
storage_url = "https://192.168.0.1:5665"
storage_user_name = "username"
storage_password = "password"
# Change the following values as required.
# Specify a list of source volume IDs of SnapOPC+ to rotate.
volume_id_list = [100001, 200001, 300001]
# If you want to schedule this script, you can use cron as follows.
# Examples: It is scheduled to rotate SnapOPC+s daily at 20:00.
# To ensure data consistency, host access must be stopped before rotation.
# crontab -e
# 0 20 * * * python3 /root/snapopcplus_rotate.py >> /root/cron.log 2>&1
class EtdxApi(EtdxBaseApi):
def __init__(self, base_url, boxid=None, proxies=None):
super().__init__(base_url, boxid=boxid, proxies=proxies)
def snapopcplus_rotate(self, volume_id_list):
"""Rotate SnapOPC+s
Args:
volume_id_list (list[int]): List of source volume IDs of SnapOPC+s
to rotate.
Returns:
list[int]: List of source volume IDs of successfully rotated
SnapOPC+.
"""
job_id_list = []
for volume_id in volume_id_list:
r = super().post("/api/v1/volume/{0!s}/snapshot/rotate"
.format(volume_id))
if r.status_code != 202:
print("Failed to request the snapshots rotation of volume "
"(ID: {0!s})".format(volume_id))
print(r)
print(r.json())
continue
job_info = (int(r.json()["job_id"]), volume_id)
job_id_list.append(job_info)
# Wait for the job completion
success_volume_id_list = []
for job_info in job_id_list:
job_id = job_info[0]
job_r = super().wait_job(job_id)
if job_r.json()["status"] != "Success":
print("Failed to rotate the snapshots of volume (ID: {0!s})"
.format(job_info[1]))
print(job_r)
print(job_r.json())
continue
success_volume_id_list.append(job_info[1])
return success_volume_id_list
def main():
storage = EtdxApi(storage_url)
# Login
if not storage.login(storage_user_name, storage_password):
return False
print("Rotating the SnapOPC+s specified by the list of source volume ID:",
volume_id_list)
# Initialize return value as True, since the procedure continues even if
# error occurs.
rtn = True
# Rotate SnapOPC+s
success_volume_list = storage.snapopcplus_rotate(volume_id_list)
if success_volume_list == []:
print("Failed to rotate all SnapOPC+s.")
return False
if set(success_volume_list) != set(volume_id_list):
print("Failed to rotate some SnapOPC+s.")
print("List of source volume IDs that failed rotation:",
list(set(volume_id_list) - set(success_volume_list)))
rtn = False
else:
print("All SnapOPC+s rotated successfully.")
# Get information of all the specified SnapOPC+s.
for volume_id in volume_id_list:
r = storage.get("/api/v1/volume/{0!s}/copysession?backup_type=snapshot"
"&is_manual_snapshot=false".format(volume_id))
print(r)
print(r.json())
# Logout
storage.logout()
return rtn
if __name__ == '__main__':
if not main():
sys.exit(1)

