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

Install pbs and pbs_ifl as loadable Python modules #1996

Merged
merged 22 commits into from
Oct 2, 2020

Conversation

toonen
Copy link
Contributor

@toonen toonen commented Aug 25, 2020

Describe Bug or Feature

These changes build and install the pbs and pbs_ifl Python modules as loadable shared library modules. This allows a standard Python 3.x interpreter to use either pbs or pbs_ifl, which is desirable for external Python programs that need to perform actions such as monitoring queued/running jobs or manipulate reservations. This also allows PTL tests to import either module to obtain constants defined by those modules and them in the validation portion of the test.

Describe Your Change

The loadable pbs_ifl module is generated from the same SWIG generated code that is statically incorporated in the PBS server and pbs_python code. The loadable pbs module is created in part by a new C module, src/modules/python/pbs_v1_module_init.c, that uses techniques similar to those used by pbs_python. Both modules are installed in %(libdir)/python/altair.

Attach Test and Valgrind Logs/Output

Two additional smoke tests were added. Please see test_import_pbs_module and test_import_pbs_ifl_module in test/tests/pbs_smoketest.py.

install-pbs-py-smoketest.log

@CLAassistant
Copy link

CLAassistant commented Aug 25, 2020

CLA assistant check
All committers have signed the CLA.

return module;
}

/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following "dummy" variable declarations and function definitions are the same as the ones in the standalone src/tools/pbs_python.c. Please merge them somehow, so that there'll be only one place to update or add to, when new functions are introduced.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. And my apologies for the delay in responding. I was on vacation for a couple of weeks and then playing catch-up. I will strip out the common code as much as seems reasonable and push an update once that is done.

Copy link
Contributor Author

@toonen toonen Sep 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I attempted to address the issue you raised about code duplication with the following commit: f548368. Please let me know if these changes are acceptable.

server_stat = pbs_ifl.pbs_statserver(server_conn, None, None)
pbs_ifl.pbs_disconnect(server_conn)
msg = "server name is %s" % (server_stat.name,)
self.logger.info(msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@checkmodule() test may not be reliable, so I suggest doing:

 diff -c pbs_smoketest.py.orig pbs_smoketest.py
*** pbs_smoketest.py.orig       2020-09-15 01:29:21.387629113 -0400
--- pbs_smoketest.py    2020-09-15 01:29:34.083629310 -0400
***************
*** 1463,1469 ****
          self.server.log_match("Req;req_reject;Reject reply code=15175",
                                max_attempts=5)
  
-     @checkModule("pbs")
      def test_import_pbs_module(self):
          """
          Test that the pbs module located in the PBS installation directory is
--- 1463,1468 ----
***************
*** 1471,1481 ****
          the PYTHONPATH environment variable contain the path
          PBS_EXEC/{lib,lib64}/python/altair.
          """
          import pbs
          msg = "pbs.JOB_STATE_RUNNING=%s" % (pbs.JOB_STATE_RUNNING,)
          self.logger.info(msg)
  
-     @checkModule("pbs_ifl")
      def test_import_pbs_ifl_module(self):
          """
          Test that the pbs_ifl module located in the PBS installation directory
--- 1470,1482 ----
          the PYTHONPATH environment variable contain the path
          PBS_EXEC/{lib,lib64}/python/altair.
          """
+         sys.path.append(os.path.join(self.server.pbs_conf['PBS_EXEC'], 'lib',
+                              'python', 'altair'))
          import pbs
          msg = "pbs.JOB_STATE_RUNNING=%s" % (pbs.JOB_STATE_RUNNING,)
          self.logger.info(msg)
  
      def test_import_pbs_ifl_module(self):
          """
          Test that the pbs_ifl module located in the PBS installation directory
***************
*** 1483,1488 ****
--- 1484,1492 ----
          This test requires the PYTHONPATH environment variable contain the path
          PBS_EXEC/{lib,lib64}/python/altair.
          """
+         sys.path.append(os.path.join(self.server.pbs_conf['PBS_EXEC'], 'lib',
+                              'python', 'altair'))
          import pbs_ifl
          server_conn = pbs_ifl.pbs_connect(None)
          server_stat = pbs_ifl.pbs_statserver(server_conn, None, None)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm more than happy to make the changes you suggest; however, I must ask, if @checkModule() is unreliable. then shouldn't it be either fixed or eliminated. I ask because I used other test code that made use of this decorator as an example, so any issues with the decorator may extend beyond the tests I added.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@toonen : I would have to check what's going on with @checkModule. Maybe it's assuming that the environment where pbs_benchpress is invoked already contains path $PBS_EXEC/lib/python/altair. Maybe I didn't have that in my path when I invoked the testsuite, and it kept failing on @checkModule. When took out that check, and explictly added the path in the test case itself, it worked. This sounds more like a fail-safe way of running the test...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bayucan: I applied the suggested patch in the following commit: 3a61204. Thanks for the suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This had the side effect of identifying an issue with -fsanitize=address, which is currently resulting in the import tests failing when that flag is included. I'm working on an autotools appropriate way to address the issue, which only reminds me that I'm a decade or so behind on frequent autotools use. :-)

@@ -1487,6 +1487,8 @@ def test_import_pbs_ifl_module(self):
PBS_EXEC/{lib,lib64}/python/altair.
"""
import pbs_ifl
sys.path.append(os.path.join(
self.server.pbs_conf['PBS_EXEC'], 'lib','python', 'altair'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'import pbs_ifl' needs to go after the ..sys.append() otherwise we'll get an import error.

libtool was not passing the -fsanitize compiler options to the compiler
when attempting to link shared libraries.
this resulted in undefined symbol errors when the library was loaded by
a program that hadn't been linked with those same -fsanitiize options.
for lib_dir in ['lib64', 'lib']:
pbs_python_path = os.path.join(self.server.pbs_conf['PBS_EXEC'],
lib_dir, 'python', 'altair')
if os.path.isdir(pbs_python_path):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to indent this if statement to be under the for loop body?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I did. Thanks for catching that! It's fixed in commit 5591dd0.

@toonen
Copy link
Contributor Author

toonen commented Sep 28, 2020

I believe I have addressed all of the issues that were pointed out. If I missed anything, please let me know.

Copy link
Contributor

@bayucan bayucan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now! This is a really nice, useful, addition to PBS. Thanks.

mv libtool libtool.orig
sed -e 's/\(-fuse-linker-plugin\)\([[|)]]\)/\1|-fsanitize=\*\2/' \
libtool.orig >libtool
rm -f libtool.orig
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the sed did something bad, we would be deleting the original libtool without checking the error status - perhaps we redirect sed output to libtool.upd (or similar name), check that the change we wanted is actually good and then mv libtool.upd to libtool when we are sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I made the modifications you suggested and also added code to generate an error file when something goes wrong. In addition, I changed the option used by sed to one that I hope is more common. The changes are in commit fa6afda.

@hirenvadalia hirenvadalia merged commit f3c242a into openpbs:master Oct 2, 2020
suresh-thelkar pushed a commit to suresh-thelkar/openpbs that referenced this pull request Oct 7, 2020
@toonen toonen deleted the install_pbs_py branch April 16, 2021 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants