######################################################################## # # All Rights Reserved. # Copyright (C) 2024, Hitachi Vantara, Ltd. # ######################################################################## # # bcmapi_cgmake - This sample script shows how to establish a copy group # by using the BCM Web API. # # This sample script assumes the following settings. # 1) The prefix and dadid are defined in the CLIDFLTS dataset. # ######################################################################## # To execute this script, need the following steps: # 1) Put bcmapi.py in the same directory as this script. # 2) Write bcmapi.ini and put it in the same directory as this script. # 3) Change the following parameters according to the environment. # 4) Execute this script from python. copyGroupID = '<copy group id to operate>' routeID = '<routelist id>' ######################################################################## import bcmapi import json import pprint # Establishes the copy pairs in the copy group. def make_cg(): # Execute the YKLOAD command before operating a copy group. # No need specifies STEM and MSG operand key. # If the PREFIX and DAD parameters are specified by using the CLIDFLTS # data set, you do not need to specify the PREFIX and DAD operand keys. # If you want to issue all commands through the command device, # replace '"' with a space character to uncomment the VIACDEV parameter. operands = "GROUP(" + copyGroupID + ") ROUTE(" + routeID + ")" \ # + " VIACDEV" rc,appData = bcmapi.bcmreq("YKLOAD", operands) if rc != 0: return 8 # You need to update information in the copy group struct # before calling the copy group operation command. Use YKQUERY or # YKEWAIT TIMEOUT(0) GOTO(SIMPLEX) NOINVALIDCHECK # to update the information. # # To identify the copy group, you need to specify the GROUP operand. # # Make sure the return value of YKQUERY is 8 or less, # instead of less than 0. # For YKQUERY, a return value of 8 indicates that at least one volume # in the specified copy group is offline, which is not necessarily # a bad state. # In YKQUERY, the return code 8 indicates that # one or more volumes in the given copy group are offline, # which is not necessarily a bad situation. operands = "GROUP(" + copyGroupID + ")" rc,appData = bcmapi.bcmreq("YKQUERY", operands) if rc > 8: return 8 # If you want to pre-check the online status of the secondary volume, # change the following three lines of '#' to blank. # If you want to pre-check online volume at secondary site, # please replace '#' to space in the following 3 lines. # if appData["copyGroup"]["secOnlineCt"] > 0: # print('Unable to YKMAKE because an online S-VOL exists.') # return 8 # Establish all SIMPLEX state copy pairs in the copy group. # To identify the copy group, you need to specify the GROUP operand. # No need specify STEM and MSG operand in the operands key's value. operands = "GROUP(" + copyGroupID + ") SELECT(COND)" rc,appData = bcmapi.bcmreq("YKMAKE", operands) if rc != 0: return 8 # Execute the YKEWAIT command, and then wait until the state of the # copy group changes to duplex. # YKEWAIT ending with a return value of 8 indicates that the copy group # has changed to an unexpected state. # To get information about a pair in an unexpected state, # execute the YKGETGRP command. rc = 4 while rc == 4: operands = "GROUP(" + copyGroupID + ")"\ + " GOTO(DUPLEX) TIMEOUT(1440)" rc,appData = bcmapi.bcmreq("YKEWAIT", operands) if rc == 8: operands = "GROUP(" + copyGroupID + ")"\ + " XSTATE(DUPLEX,PENDING)" rc,appData = bcmapi.bcmreq("YKGETGRP", operands) if rc == 0: print(appData["copyGroup"]) return 8 elif rc != 0: return 8 return 0 tsoStart = False bcmStart = False # Before using the BCM Web API, you need to perform # z/OSMF authentication, start a TSO/E session, # and then start the BCM Web API server. respBody = bcmapi.start_tso() if respBody != "": tsoStart = True respBody = bcmapi.start_bcm() if respBody != "": bcmStart = True rc = make_cg() # To exit the BCM Web API server, # you need to send a "submit":"exit" request. if bcmStart: respBody = bcmapi.end_bcm() # You must send DELETE /zosmf/tsoApp/tso/<servletKey> # to terminate TSO/E address space of BCM Web API server. if tsoStart: respBody = bcmapi.end_tso() exit()