########################################################################
#
# All Rights Reserved. Copyright (C) 2023, Hitachi, 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()