CiscoTestAutomation / genielibs

genie.libs contains libraries for configuring, retrieving and testing topologies
Apache License 2.0
107 stars 53 forks source link

copy_to_device always fails under IOS-XR #138

Closed ZacharyPuls closed 9 months ago

ZacharyPuls commented 10 months ago

In genielibs/pkgs/clean-pkg/src/genie/libs/clean/stages/stages.py line 1208, device.api.copy_to_device checks for a non-None return value:

res = device.api.\
    copy_to_device(protocol=protocol,
                server=file_utils.get_hostname(server) if server else None,
                remote_path=file,
                local_path=renamed_local_path,
                vrf=vrf,
                timeout=timeout,
                compact=compact,
                use_kstack=use_kstack,
                interface=interface,
                overwrite=overwrite,
                prompt_recovery=prompt_recovery,
                **kwargs)
if not res:
    raise Exception('Failed to copy file to device')

This returns the result of FileUtils.copyfile (genielibs/pkgs/sdk-pkg/src/genie/libs/sdk/apis/utils.py, lines 913-931):

if vrf is not None:
    return fu.copyfile(source=source,
                       destination=local_path,
                       device=device,
                       vrf=vrf,
                       timeout_seconds=timeout,
                       compact=compact,
                       use_kstack=use_kstack,
                       protocol=protocol,
                       **kwargs)
else:
    return fu.copyfile(source=source,
                       destination=local_path,
                       device=device,
                       timeout_seconds=timeout,
                       compact=compact,
                       use_kstack=use_kstack,
                       protocol=protocol,
                       **kwargs)

Which, on IOS-XR (genielibs/pkgs/filetransferutils-pkg/src/genie/libs/filetransferutils/plugins/iosxr/fileutils.py, line 20) always returns None:

def copyfile(self,
             source,
             destination,
             timeout_seconds=300,
             vrf=None,
             *args,
             **kwargs):
    """ Copy a file to/from IOSXR device
[snip]
        Returns
        -------
            `None`

This is causing copy_to_device to always fail when run via pyats clean (output from a sample device):

2023-10-30T18:53:36: %AETEST-INFO: +------------------------------------------------------------------------------+
2023-10-30T18:53:36: %AETEST-INFO: |                         Starting stage CopyToDevice                          |
2023-10-30T18:53:36: %AETEST-INFO: +------------------------------------------------------------------------------+
[snip]
2023-10-30T18:53:37: %AETEST-INFO: +..............................................................................+
2023-10-30T18:53:37: %AETEST-INFO: :    Starting STEP 4: Copying image file labncs62.cfg to device LABNCS62 ha    :
2023-10-30T18:53:37: %AETEST-INFO: :                                   rddisk:/                                   :
2023-10-30T18:53:37: %AETEST-INFO: +..............................................................................+

2023-10-30 18:53:37,729: %UNICON-INFO: +++ LABNCS62 with via 'cli': executing command 'copy ftp://anonymous:anonymous@10.10.99.137/labncs62.cfg harddisk:/labncs62.cfg vrf Mgmt-intf' +++
copy ftp://anonymous:anonymous@10.10.99.137/labncs62.cfg harddisk:/labncs62.cfg vrf Mgmt-intf
Mon Oct 30 21:30:20.711 CDT
Destination filename [/harddisk:/labncs62.cfg]?/labncs62.cfg
Accessing ftp://anonymous:*@10.10.99.137;Mgmt-intf/labncs62.cfg
CC
22647 bytes copied in      0 sec

Copy operation success
RP/0/RP0/CPU0:LABNCS62#
2023-10-30T18:53:38: %GENIE-WARNING: Attempt #1: Unable to copy labncs62.cfg to 'LABNCS62 harddisk:/' due to:
2023-10-30T18:53:38: %GENIE-WARNING: Failed to copy file to device
2023-10-30T18:53:38: %GENIE-INFO: Sleeping for 30 seconds before retrying

I'd recommend correcting this by removing lines 1221-1222 of genielibs/pkgs/clean-pkg/src/genie/libs/clean/stages/stages.py:

if not res:
    raise Exception('Failed to copy file to device')

As the task will fail when the copy fails, as device.api.copy_to_device will propagate an Exception if the copy operation fails.

SohanTirpude commented 10 months ago

Hello @ZacharyPuls,

This is strange, but rather than removing the error handling, I will be looking at why the copyfile returns None for IOSXR devices. So, kindly give me some time to analyse and debug the issue.

Thank you.

SohanTirpude commented 10 months ago

Hello @ZacharyPuls,

I think I have found the issue the repo.

For iosxe, if you check the method copyfile defined in iosxe/fileutils.py#L118, this method returns the output of copyfile of parent class FileUtilsDeviceBase which is defined in plugins/fileutils.py#L92 which again return the output of send_cli_to_device which is defined in filetransferutils/fileutils.py#L39 which returns the output execute API. And hence, for iosxe this issue is not seen because it is return something than None. Now, as per the function documentation it is wrong because it is not returning the None.

Now, for iosxr, the method copyfile defined in iosxr/fileutils.py#L20 doesn't return the output of copyfile of parent class FileUtilsDeviceBase and hence by default it is returning None. So, if we make the change in this file to return the output of copyfile of parent class FileUtilsDeviceBase then I think this issue will be resolved.

Can you please add return here iosxr/fileutils.py#L122 and let me know if this fixes the issue or not?

Thank you.

SohanTirpude commented 10 months ago

Hello @ZacharyPuls,

Did you get a chance to test it again with above mentioned changes? Kindly let me know.

Thank you.

SohanTirpude commented 9 months ago

Hello @ZacharyPuls,

Did you try with above mentioned solution? Kindly let me know.

Thank you.

SohanTirpude commented 9 months ago

Hello @ZacharyPuls,

I have raised the PR for this issue. I will update you once this PR gets merged. Thank you.

ZacharyPuls commented 9 months ago

I apologize for the delay in response, it's taken me a bit to get back to this. I can confirm this works on our lab device.

SohanTirpude commented 9 months ago

Hello @ZacharyPuls,

No problem and thanks for confirmation. I have already merged the PR as well, so in the upcoming pyATS version this fix will be available. Hence, I am closing this ticket, if you still see this issue with newer pyATS version, then kindly let me know.

Thank you.