Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bugfix][1856][zos_mount]Fails_using_persistat_option #1871

Open
wants to merge 47 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
eab8a05
First iteration
AndreMarcel99 Jan 7, 2025
a99f883
First iteration
AndreMarcel99 Jan 7, 2025
5efe945
Merge branch 'dev' into bugfix/1856/fails_when_add_option_to_update_d…
AndreMarcel99 Jan 13, 2025
9174060
Replace calls for blockinfile
AndreMarcel99 Jan 15, 2025
6566eb0
Solution on propose
AndreMarcel99 Jan 16, 2025
829d84b
Fix bad code
AndreMarcel99 Jan 16, 2025
0ff7610
Revert issues on copy
AndreMarcel99 Jan 16, 2025
6b9450a
Full return of zos copy
AndreMarcel99 Jan 16, 2025
7a724b1
Add fragment
AndreMarcel99 Jan 16, 2025
4a28973
Debug
AndreMarcel99 Jan 16, 2025
b4dacc6
Debug
AndreMarcel99 Jan 16, 2025
5b444cc
Debug
AndreMarcel99 Jan 16, 2025
e767c0d
Merge branch 'dev' into bugfix/1856/fails_when_add_option_to_update_d…
AndreMarcel99 Jan 17, 2025
4de599f
Fix bassic mount
AndreMarcel99 Jan 21, 2025
3e5a192
Remove for test and validate write option
AndreMarcel99 Jan 21, 2025
ad4b26e
Space
AndreMarcel99 Jan 21, 2025
33c21e5
Merge branch 'dev' into bugfix/1856/fails_when_add_option_to_update_d…
AndreMarcel99 Jan 21, 2025
18f5c5c
Fix ansible lint
AndreMarcel99 Jan 21, 2025
8fab611
Update changelogs/fragments/1871-Failing_using_persistent_option.yml
AndreMarcel99 Jan 21, 2025
6d66ac6
Fix check if work properly
AndreMarcel99 Jan 21, 2025
7ff2de7
Fix check if work properly
AndreMarcel99 Jan 21, 2025
5ef0316
Enhance validation
AndreMarcel99 Jan 21, 2025
f5b1fc4
Fix lint
AndreMarcel99 Jan 21, 2025
ba40d89
Fix try catch
AndreMarcel99 Jan 21, 2025
69887ae
Fix ansible lint
AndreMarcel99 Jan 21, 2025
1366201
Add test case to validate change
AndreMarcel99 Jan 22, 2025
871bc79
Add test case to validate change
AndreMarcel99 Jan 22, 2025
fe82780
Add test case to validate change
AndreMarcel99 Jan 22, 2025
2e3833d
Add test case to validate change
AndreMarcel99 Jan 22, 2025
d6754e3
Add test case to validate change
AndreMarcel99 Jan 22, 2025
0b5ba82
Add test case to validate change
AndreMarcel99 Jan 22, 2025
6f03eed
Add test case to validate change
AndreMarcel99 Jan 22, 2025
0c9028b
Add test case to validate change
AndreMarcel99 Jan 22, 2025
893e0b6
Fix removal and check
AndreMarcel99 Jan 22, 2025
4f8fa17
Fix removal and check
AndreMarcel99 Jan 22, 2025
f4ac77b
Fix removal and check
AndreMarcel99 Jan 22, 2025
d884f03
Fix removal and check
AndreMarcel99 Jan 22, 2025
0ab6e38
Fix removal and check
AndreMarcel99 Jan 22, 2025
8bc90da
Fix removal and check
AndreMarcel99 Jan 22, 2025
622cbee
Fix removal and check
AndreMarcel99 Jan 22, 2025
7012fa8
Fix removal and check
AndreMarcel99 Jan 22, 2025
278ca75
Merge branch 'dev' into bugfix/1856/fails_when_add_option_to_update_d…
AndreMarcel99 Jan 22, 2025
4be249e
Delete line
AndreMarcel99 Jan 25, 2025
c7c77f4
Write no utf-8 characters
AndreMarcel99 Jan 25, 2025
674cc3b
Use blockinfile
AndreMarcel99 Jan 25, 2025
ac06ee3
Use blockinfile
AndreMarcel99 Jan 25, 2025
5fb4423
Use blockinfile
AndreMarcel99 Jan 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelogs/fragments/1871-Failing_using_persistent_option.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bugfixes:
- zos_mount - Module failed when using persistent option with a data set that contains non UTF-8 characters. Fix now can use a data set with non UTF-8 characters as data_store.
(https://github.com/ansible-collections/ibm_zos_core/pull/1871).
169 changes: 65 additions & 104 deletions plugins/modules/zos_mount.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@

import os
import re
import tempfile
import traceback

from datetime import datetime
from ansible.module_utils.basic import AnsibleModule
Expand All @@ -547,10 +547,15 @@
data_set,
backup as Backup,
)
from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.copy import (
copy_uss_mvs
from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.import_handler import (
ZOAUImportError,
)

try:
from zoautil_py import datasets
except Exception:
datasets = ZOAUImportError(traceback.format_exc())


# This is a duplicate of backupOper found in zos_apf.py of this collection
# Ansible doesn't want to import things not in the module_utils folder,
Expand Down Expand Up @@ -610,80 +615,53 @@ def mt_backupOper(module, src, backup, tmphlq=None):
return backup_name


def swap_text(original, adding, removing):
"""swap_text returns original after removing blocks matching removing,
and adding the adding param.
original now should be a list of lines without newlines.
return is the consolidated file value.
def get_str_to_keep(dataset, src):
"""Get the content of previous statements by the module to remove it.

Parameters
----------
original : str
Text to modify.
adding : str
Lines to add.
removing : str
Lines to delete if matched.
dataset : str
Dataset for persistant.
src : str
Name of zfs dataset.

Returns
-------
str
The consolidated file value.
list
head_content.
list
tail_content.
"""
content_lines = original

remove_starting_at_index = None
remove_ending_at_index = None

ms = re.compile(r"^\s*MOUNT\s+FILESYSTEM\(\s*'" + removing.upper() + r"'\s*\)")
removable = dict()

for index, line in enumerate(content_lines):
if remove_starting_at_index is None:
if ms.match(line) is not None:
remove_starting_at_index = index
# Check for comments above the match line
if index > 0:
for tmpindex in range(index - 1, 0, -1):
tmpline = content_lines[tmpindex]
if len(tmpline) > 0:
# Added the second test to handle adjacent entries
if tmpline[0:2] != "/*" or tmpline[0:6] == "/* BEG":
remove_starting_at_index = tmpindex
break
else:
remove_starting_at_index = tmpindex
break
remove_ending_at_index = index
continue
if remove_starting_at_index is not None:
remove_ending_at_index = index
doit = False
if len(line) > 0:
if line[0] != " " and line[0] != "\t" and line[0:2] != "/*":
doit = True
elif line[0:6] == "/* END":
doit = True
else:
doit = True
if doit:
removable[remove_starting_at_index] = remove_ending_at_index
remove_starting_at_index = None
remove_ending_at_index = None
content = datasets.read(dataset=dataset).split("\n")
line_counter = 0
pattern = re.compile(r"^\s*MOUNT\s+FILESYSTEM\(\s*'" + src.upper() + r"'\s*\)")

if remove_starting_at_index is not None:
if remove_ending_at_index is not None:
if remove_starting_at_index != remove_ending_at_index:
removable[remove_starting_at_index] = remove_ending_at_index
for line in content:
if pattern.match(line) is not None:
line_counter += 1
break
line_counter += 1

for startidx in reversed(removable.keys()):
endidx = removable[startidx]
del content_lines[startidx: endidx + 1]
begin_block_code = line_counter
for line in reversed(content[:line_counter]):
if "/* BEGIN ANSIBLE MANAGED" in line:
begin_block_code -= 1
break
begin_block_code -= 1

if len(adding) > 0:
content_lines.extend(adding.split("\n"))
end_block_code = line_counter
for line in content[line_counter:]:
if "/* END ANSIBLE MANAGED" in line:
end_block_code += 1
break
end_block_code += 1

return "\n".join(content_lines)
head_content = content[:begin_block_code]
tail_content = content[end_block_code + 1:]

head_content.extend(tail_content)

return head_content


# #############################################################################
Expand Down Expand Up @@ -863,10 +841,7 @@ def run_module(module, arg_def):
# ##########################################
# Assemble the mount command

d = datetime.today()
dtstr = d.strftime("%Y%m%d-%H%M%S")
parmtext = "/* BEGIN ANSIBLE MANAGED BLOCK " + dtstr + " */\n"
parmtail = "\n" + parmtext.replace("BEGIN", "END")
parmtext = ""

if comment is not None:
extra = ""
Expand Down Expand Up @@ -975,7 +950,7 @@ def run_module(module, arg_def):
if len(automove_list) > 1:
fullcmd = fullcmd + "(" + automove_list + ")"
parmtext = parmtext + "(" + automove_list + ")"
parmtext = parmtext + parmtail

else:
parmtext = ""

Expand Down Expand Up @@ -1040,45 +1015,31 @@ def run_module(module, arg_def):
stderr=str(res_args),
)

tmp_file = tempfile.NamedTemporaryFile(delete=True)
tmp_file_filename = tmp_file.name
tmp_file.close()
bk_ds = datasets.tmp_name(high_level_qualifier=tmphlq)
datasets.create(name=bk_ds, dataset_type="SEQ")

copy_uss_mvs(data_store, tmp_file_filename, is_binary=False)
new_str = get_str_to_keep(dataset=data_store, src=src)

module.run_command(
"chtag -tc ISO8859-1 " + tmp_file_filename, use_unsafe_shell=False, errors='replace'
)
rc_write = 0

with open(tmp_file_filename, "r") as fh:
content = fh.read().splitlines()
for line in new_str:
rc_write = datasets.write(dataset_name=bk_ds, content=line.rstrip(), append=True)
if rc_write != 0:
datasets.delete(dataset=bk_ds)
break

cont = list()
if rc_write == 0:
datasets.delete(dataset=data_store)
datasets.copy(source=bk_ds, target=data_store)
datasets.delete(dataset=bk_ds)

if stdout is None:
stdout = " "

# removing null entries
for line in content:
if line is not None:
if len(line) > 0:
if (line[0:1] is not None) and (line[0:1] != "\u0000"):
cont.append(line)

stdout += "\n"
newtext = swap_text(cont, parmtext, src)
if newtext != cont or cont != content:
fh = open(tmp_file_filename, "w")
fh.write(newtext)
fh.close()
# pre-clear to prevent caching behavior on the copy-back
module.run_command(
"mrm " + data_store, use_unsafe_shell=False, errors='replace'
)
copy_uss_mvs(tmp_file_filename, data_store, is_binary=True)
if will_mount:
d = datetime.today()
dtstr = d.strftime("%Y%m%d-%H%M%S")
marker = '/* {mark} ANSIBLE MANAGED BLOCK ' + dtstr + " */"
marker = "{0}\\n{1}\\n{2}".format("BEGIN", "END", marker)

if os.path.isfile(tmp_file_filename):
os.unlink(tmp_file_filename)
datasets.blockinfile(dataset=data_store, state=True, block=parmtext, marker=marker, insert_after="EOF")

if rc == 0:
if stdout is None:
Expand Down
5 changes: 0 additions & 5 deletions tests/functional/modules/test_zos_mount_func.py
fernandofloresg marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,6 @@ def test_basic_mount_with_bpx_comment_backup(ansible_zos_module, volumes_on_syst
is_binary=True,
remote_src=True,
)
hosts.all.shell(
cmd="chtag -t -c ISO8859-1 " + test_tmp_file_filename,
executable=SHELL_EXECUTABLE,
stdin="",
)
results = hosts.all.shell(
cmd="cat " + test_tmp_file_filename, executable=SHELL_EXECUTABLE, stdin=""
)
Expand Down
Loading