Skip to content

Commit 4f4c264

Browse files
authored
zos_data_set - add force parameter to enable member delete via disp shr (#718)
* add force parameter to enable member delete via disp shr Signed-off-by: Ketan Kelkar <ktnklkr@gmail.com> * update link to PR instead of issue Signed-off-by: Ketan Kelkar <ktnklkr@gmail.com> * fix minor mistake in func test Signed-off-by: Ketan Kelkar <ktnklkr@gmail.com> * update DOCstring for missed items highlighted in PR review Signed-off-by: Ketan Kelkar <ktnklkr@gmail.com> * update copyright years in data set module util Signed-off-by: Ketan Kelkar <ktnklkr@gmail.com> --------- Signed-off-by: Ketan Kelkar <ktnklkr@gmail.com>
1 parent d361802 commit 4f4c264

File tree

4 files changed

+226
-6
lines changed

4 files changed

+226
-6
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
minor_changes:
2+
- zos_data_set - add force parameter to enable member delete while pdse is in use (https://github.com/ansible-collections/ibm_zos_core/pull/718).

plugins/module_utils/data_set.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) IBM Corporation 2020
1+
# Copyright (c) IBM Corporation 2020, 2023
22
# Licensed under the Apache License, Version 2.0 (the "License");
33
# you may not use this file except in compliance with the License.
44
# You may obtain a copy of the License at
@@ -116,6 +116,7 @@ def ensure_present(
116116
sms_management_class=None,
117117
volumes=None,
118118
tmp_hlq=None,
119+
force=None,
119120
):
120121
"""Creates data set if it does not already exist.
121122
@@ -171,6 +172,8 @@ def ensure_present(
171172
has GUARANTEED_SPACE=YES specified. Otherwise, the allocation will fail.
172173
Defaults to None.
173174
tmp_hlq (str, optional): High level qualifier for temporary datasets.
175+
force (bool, optional): Used to determine behavior when performing member operations on a pdse.
176+
Defaults to None.
174177
175178
Returns:
176179
bool -- Indicates if changes were made.
@@ -247,11 +250,11 @@ def ensure_member_present(name, replace=False):
247250
return True
248251

249252
@staticmethod
250-
def ensure_member_absent(name):
253+
def ensure_member_absent(name, force=False):
251254
"""Deletes provided data set member if it exists.
252255
Returns a boolean indicating if changes were made."""
253256
if DataSet.data_set_member_exists(name):
254-
DataSet.delete_member(name)
257+
DataSet.delete_member(name, force)
255258
return True
256259
return False
257260

@@ -772,6 +775,7 @@ def replace(
772775
sms_management_class=None,
773776
volumes=None,
774777
tmp_hlq=None,
778+
force=None,
775779
):
776780
"""Attempts to replace an existing data set.
777781
@@ -826,6 +830,8 @@ def replace(
826830
has GUARANTEED_SPACE=YES specified. Otherwise, the allocation will fail.
827831
Defaults to None.
828832
tmp_hlq (str, optional): High level qualifier for temporary datasets.
833+
force (bool, optional): Used to determine behavior when performing member operations on a pdse.
834+
Defaults to None.
829835
"""
830836
arguments = locals()
831837
DataSet.delete(name)
@@ -884,6 +890,7 @@ def create(
884890
sms_management_class=None,
885891
volumes=None,
886892
tmp_hlq=None,
893+
force=None,
887894
):
888895
"""A wrapper around zoautil_py
889896
Dataset.create() to raise exceptions on failure.
@@ -940,6 +947,8 @@ def create(
940947
has GUARANTEED_SPACE=YES specified. Otherwise, the allocation will fail.
941948
Defaults to None.
942949
tmp_hlq (str, optional): High level qualifier for temporary datasets.
950+
force (bool, optional): Used to determine behavior when performing member operations on a pdse.
951+
Defaults to None.
943952
Raises:
944953
DatasetCreateError: When data set creation fails.
945954
"""
@@ -992,7 +1001,7 @@ def create_member(name):
9921001
raise DatasetMemberCreateError(name, rc)
9931002

9941003
@staticmethod
995-
def delete_member(name):
1004+
def delete_member(name, force=False):
9961005
"""A wrapper around zoautil_py
9971006
Dataset.delete_members() to raise exceptions on failure.
9981007
@@ -1002,7 +1011,7 @@ def delete_member(name):
10021011
Raises:
10031012
DatasetMemberDeleteError: When data set member deletion fails.
10041013
"""
1005-
rc = datasets.delete_members(name)
1014+
rc = datasets.delete_members(name, force=force)
10061015
if rc > 0:
10071016
raise DatasetMemberDeleteError(name, rc)
10081017

plugins/modules/zos_data_set.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
- >
4444
If I(state=absent) and the data set does exist on the managed node,
4545
remove the data set, module completes successfully with I(changed=True).
46+
- >
47+
If I(state=absent) and I(type=MEMBER) and I(force=True), the data set
48+
will be opened with I(DISP=SHR) such that the entire data set can be
49+
accessed by other processes while the specified member is deleted.
4650
- >
4751
If I(state=absent) and I(volumes) is provided, and the data set is not
4852
found in the catalog, the module attempts to perform catalog using supplied
@@ -247,6 +251,20 @@
247251
that is not available, then the value C(TMPHLQ) is used.
248252
required: false
249253
type: str
254+
force:
255+
description:
256+
- Specifies that the data set can be shared with others during a member
257+
delete operation which results in the data set you are updating to be
258+
simultaneously updated by others.
259+
- This is helpful when a data set is being used in a long running process
260+
such as a started task and you are wanting to delete a member.
261+
- The I(force=True) option enables sharing of data sets through the
262+
disposition I(DISP=SHR).
263+
- The I(force=True) only applies to data set members when I(state=absent)
264+
and I(type=MEMBER).
265+
type: bool
266+
required: false
267+
default: false
250268
batch:
251269
description:
252270
- Batch can be used to perform operations on multiple data sets in a single module call.
@@ -271,6 +289,11 @@
271289
- >
272290
If I(state=absent) and the data set does exist on the managed node,
273291
remove the data set, module completes successfully with I(changed=True).
292+
- >
293+
If I(state=absent) and I(type=MEMBER) and I(force=True), the data
294+
set will be opened with I(DISP=SHR) such that the entire data set
295+
can be accessed by other processes while the specified member is
296+
deleted.
274297
- >
275298
If I(state=absent) and I(volumes) is provided, and the data set is not
276299
found in the catalog, the module attempts to perform catalog using supplied
@@ -467,6 +490,21 @@
467490
type: bool
468491
required: false
469492
default: false
493+
force:
494+
description:
495+
- Specifies that the data set can be shared with others during a member
496+
delete operation which results in the data set you are updating to
497+
be simultaneously updated by others.
498+
- This is helpful when a data set is being used in a long running
499+
process such as a started task and you are wanting to delete a
500+
member.
501+
- The I(force=True) option enables sharing of data sets through the
502+
disposition I(DISP=SHR).
503+
- The I(force=True) only applies to data set members when
504+
I(state=absent) and I(type=MEMBER).
505+
type: bool
506+
required: false
507+
default: false
470508
471509
"""
472510
EXAMPLES = r"""
@@ -552,6 +590,13 @@
552590
state: absent
553591
type: MEMBER
554592
593+
- name: Remove a member from an existing PDS/E by opening with disposition DISP=SHR
594+
zos_data_set:
595+
name: someds.name.here(mydata)
596+
state: absent
597+
type: MEMBER
598+
force: yes
599+
555600
- name: Create multiple partitioned data sets and add one or more members to each
556601
zos_data_set:
557602
batch:
@@ -894,14 +939,17 @@ def perform_data_set_operations(name, state, **extra_args):
894939
"""Calls functions to perform desired operations on
895940
one or more data sets. Returns boolean indicating if changes were made."""
896941
changed = False
942+
# passing in **extra_args forced me to modify the acceptable parameters
943+
# for multiple functions in data_set.py including ensure_present, replace
944+
# and create where the force parameter has no bearing.
897945
if state == "present" and extra_args.get("type") != "MEMBER":
898946
changed = DataSet.ensure_present(name, **extra_args)
899947
elif state == "present" and extra_args.get("type") == "MEMBER":
900948
changed = DataSet.ensure_member_present(name, extra_args.get("replace"))
901949
elif state == "absent" and extra_args.get("type") != "MEMBER":
902950
changed = DataSet.ensure_absent(name, extra_args.get("volumes"))
903951
elif state == "absent" and extra_args.get("type") == "MEMBER":
904-
changed = DataSet.ensure_member_absent(name)
952+
changed = DataSet.ensure_member_absent(name, extra_args.get("force"))
905953
elif state == "cataloged":
906954
changed = DataSet.ensure_cataloged(name, extra_args.get("volumes"))
907955
elif state == "uncataloged":
@@ -1017,6 +1065,11 @@ def parse_and_validate_args(params):
10171065
aliases=["volume"],
10181066
dependencies=["state"],
10191067
),
1068+
force=dict(
1069+
type="bool",
1070+
required=False,
1071+
default=False,
1072+
),
10201073
),
10211074
),
10221075
# For individual data set args
@@ -1086,6 +1139,11 @@ def parse_and_validate_args(params):
10861139
required=False,
10871140
default=None
10881141
),
1142+
force=dict(
1143+
type="bool",
1144+
required=False,
1145+
default=False,
1146+
),
10891147
mutually_exclusive=[
10901148
["batch", "name"],
10911149
# ["batch", "state"],
@@ -1102,6 +1160,7 @@ def parse_and_validate_args(params):
11021160
["batch", "key_length"],
11031161
# ["batch", "replace"],
11041162
["batch", "volumes"],
1163+
# ["batch", "force"],
11051164
],
11061165
)
11071166
parser = BetterArgParser(arg_defs)
@@ -1162,6 +1221,11 @@ def run_module():
11621221
default=False,
11631222
),
11641223
volumes=dict(type="raw", required=False, aliases=["volume"]),
1224+
force=dict(
1225+
type="bool",
1226+
required=False,
1227+
default=False,
1228+
),
11651229
),
11661230
),
11671231
# For individual data set args
@@ -1213,6 +1277,11 @@ def run_module():
12131277
required=False,
12141278
default=None
12151279
),
1280+
force=dict(
1281+
type="bool",
1282+
required=False,
1283+
default=False
1284+
),
12161285
)
12171286
result = dict(changed=False, message="", names=[])
12181287

0 commit comments

Comments
 (0)