Skip to content

Added a sub-command to show if packages are relocatable#9199

Merged
gartung merged 9 commits intospack:developfrom
epfl-scitas:features/buildcache_preview
Feb 28, 2019
Merged

Added a sub-command to show if packages are relocatable#9199
gartung merged 9 commits intospack:developfrom
epfl-scitas:features/buildcache_preview

Conversation

@alalazo
Copy link
Copy Markdown
Member

@alalazo alalazo commented Sep 10, 2018

closes #9188

This implements the idea discussed in the ticket above. From user perspective a sample output is:

$ spack buildcache preview hdf5
Relocatable nodes
--------------------------------
[-]  [email protected]%[email protected]~cxx~debug~fortran~hl~mpi+pic+shared+szip~threadsafe arch=linux-ubuntu18.04-x86_64 
[+]      ^[email protected]%[email protected] arch=linux-ubuntu18.04-x86_64 
[+]      ^[email protected]%[email protected]+optimize+pic+shared arch=linux-ubuntu18.04-x86_64 

meaning that in this DAG hdf5 might not be relocatable, while libszip and zlib surely are.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Sep 10, 2018

This PR still needs work to make the sub-command portable. Anyhow I wanted to submit it early so that people could start to play with it, and check if their packages of interest are or are not 100% relocatable. For instance, a worrying thing is:

$ spack buildcache preview mpich
Relocatable nodes
--------------------------------
[-]  [email protected]%[email protected] device=ch3 +hydra netmod=tcp +pmi+romio~verbs arch=linux-ubuntu18.04-x86_64 

I suspect most of the times Spack's root directory (or any subfolder) is present in the data segment just to be used in help strings, but I can't think of a reliable way to ensure that the package remains relocatable.

Copy link
Copy Markdown
Member

@gartung gartung left a comment

Choose a reason for hiding this comment

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

Looks OK to me.

@gartung
Copy link
Copy Markdown
Member

gartung commented Sep 10, 2018

@alalazo Tk is the only package that I know of the uses a compiled in path to locate its config file. Other strings can probably be safely ignored. This is why I added the option (-a) to create the buildcache anyway.

Copy link
Copy Markdown
Member

@tgamblin tgamblin left a comment

Choose a reason for hiding this comment

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

@alalazo: this looks great to me but coverage is only 35%.

Could we make a test that builds trivial relocatable and non-relocatable binaries? I think this would be the first spack test to actually compile something, but it seems worth it to me. We could skip the test if clang or gcc is unavailable via spack compilers. What do you think?

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Sep 16, 2018

Could we make a test that builds trivial relocatable and non-relocatable binaries? I think this would be the first spack test to actually compile something, but it seems worth it to me. We could skip the test if clang or gcc is unavailable via spack compilers. What do you think?

Definitely worth to come up with some tests. Also, pointing this out to be sure you saw it: this PR currently works only for linux, as I don't have a MacOS to try something similar:

if platform.system().lower() != 'linux':
msg = 'function currently implemented only for linux'
raise NotImplementedError(msg)

@alalazo alalazo force-pushed the features/buildcache_preview branch 2 times, most recently from f726b45 to 45f2065 Compare September 19, 2018 10:06
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Sep 19, 2018

To proceed with this PR I had to write something that skips tests if I don't find certain executables:

@pytest.fixture(autouse=True)
def _skip_if_missing_executables(request):
"""Permits to mark tests with 'require_executables' and skip the
tests if the executables passed as arguments are not found.
"""
if request.node.get_marker('requires_executables'):
required_execs = request.node.get_marker('requires_executables').args
missings_execs = [
x for x in required_execs if spack.util.executable.which(x) is None
]
if missings_execs:
msg = 'could not find executables: {0}'
pytest.skip(msg.format(', '.join(missings_execs)))

It's used like this:

@pytest.mark.requires_executables(
'/usr/bin/gcc', 'patchelf', 'strings', 'file'
)
def test_file_is_relocatable(source_file, is_relocatable):
compiler = spack.util.executable.which('/usr/bin/gcc')
executable = str(source_file).replace('.c', '.x')
compiler(str(source_file), '-o', executable)
assert spack.relocate.file_is_relocatable(executable) is is_relocatable

I was wondering if we should move this up the test folder, maybe in conftest.py. Could this be useful elsewhere?

@alalazo alalazo force-pushed the features/buildcache_preview branch 5 times, most recently from d52c5c6 to af0380e Compare September 19, 2018 17:29
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Sep 19, 2018

@tgamblin I think I addressed your comments here, let me know if other changes are necessary.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Sep 30, 2018

ping

@alalazo alalazo force-pushed the features/buildcache_preview branch from af0380e to c070293 Compare October 21, 2018 19:10
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Oct 21, 2018

@tgamblin Rebased and ready for a further review.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Nov 14, 2018

@tgamblin

@pramodk
Copy link
Copy Markdown
Contributor

pramodk commented Dec 8, 2018

I suspect most of the times Spack's root directory (or any subfolder) is present in the data segment just to be used in help strings, but I can't think of a reliable way to ensure that the package remains relocatable.

We recently started using buildcache. I see that common packages like gcc, python, sqlite are not relocatable if we just check with strings. I wonder if there should be a property in in package.py that we can start adding (as we test packages) which can override checks like strings.

@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Dec 10, 2018

I see that common packages like gcc, python, sqlite are not relocatable if we just check with strings.

As far as I understand packages that contain strings referring to the installation path can't be insured to be relocatable. If you have <prefix> in the data segment I assume there's no way to check if you are using it "just" to display text to a user or if you are using the path as part of your application logic.

I wonder if there should be a property in in package.py that we can start adding (as we test packages) which can override checks like strings.

Do you mean override the check so that it passes the query on relocatability, while with strings it does not? As long as we don't have reliable ways to substitute strings in a binary I don't know if that's a good idea. We would just hide the issue while not solving it.

That said, my understanding of this subject is quite naive at the moment. There are a couple of projects, like exodus, that I want to have a look at to see how they approach the issue. Also: if anybody has good references on the subject of relocating binaries, feel free to post them here (I would be glad to read them).

@alalazo alalazo force-pushed the features/buildcache_preview branch from c070293 to 97cc493 Compare December 10, 2018 09:18
Copy link
Copy Markdown
Member

@gartung gartung left a comment

Choose a reason for hiding this comment

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

This looks OK to me. You will have to rebase on develop once all of the other changes to buildcache.py and relocate.py go in.

@alalazo alalazo force-pushed the features/buildcache_preview branch from 97cc493 to 91c3e1f Compare January 15, 2019 16:33
@alalazo
Copy link
Copy Markdown
Member Author

alalazo commented Jan 15, 2019

@gartung @tgamblin Rebased and ready for another review.

@gartung
Copy link
Copy Markdown
Member

gartung commented Feb 22, 2019

I got around to testing this as an alternative to --allow-root. It tries to run on all files under /usr/ for external packages. The mime type misidentifies files as ELF that are not.

==> 'file' '-b' '--mime-type' '/build/work/spack-data/install/linux-rhel7-x86_64/gcc-7.3.0/root-6.12.06-i7e2sbt2pstdfhfm7tzgwf4z6hnnguke/etc/allDict.cxx.pch'
==> [MIME_TYPE] /build/work/spack-data/install/linux-rhel7-x86_64/gcc-7.3.0/root-6.12.06-i7e2sbt2pstdfhfm7tzgwf4z6hnnguke/etc/allDict.cxx.pch -> application/octet-stream
==> [/build/work/spack-data/install/linux-rhel7-x86_64/gcc-7.3.0/root-6.12.06-i7e2sbt2pstdfhfm7tzgwf4z6hnnguke/etc/allDict.cxx.pch] -> BINARY FILE
==> 'strings' '/build/work/spack-data/install/linux-rhel7-x86_64/gcc-7.3.0/root-6.12.06-i7e2sbt2pstdfhfm7tzgwf4z6hnnguke/etc/allDict.cxx.pch'
==> 'patchelf' '--print-rpath' '/build/work/spack-data/install/linux-rhel7-x86_64/gcc-7.3.0/root-6.12.06-i7e2sbt2pstdfhfm7tzgwf4z6hnnguke/etc/allDict.cxx.pch'
not an ELF executable

@gartung
Copy link
Copy Markdown
Member

gartung commented Feb 22, 2019

@tgamblin I think this is ready for merging.
@alalazo Binaries which are built with debug info will have the source file path from the build stage. This usually still contains spack.store.layout.root so those packages will come up as not relocatable.

@gartung gartung requested a review from tgamblin February 22, 2019 22:36
@scheibelp scheibelp self-assigned this Feb 28, 2019
@scheibelp scheibelp dismissed tgamblin’s stale review February 28, 2019 19:07

Test coverage is now substantially improved as requested

assert spack.relocate.file_is_relocatable(executable) is is_relocatable


@pytest.mark.skipif(
Copy link
Copy Markdown
Member Author

@alalazo alalazo Feb 28, 2019

Choose a reason for hiding this comment

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

@gartung Can this skip_if be removed now that you added an implementation for darwin?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yes

@gartung gartung merged commit e3af8ed into spack:develop Feb 28, 2019
gartung added a commit to gartung/spack that referenced this pull request Feb 28, 2019
…unctions introduced in

spack#9199

Instead of replacing rpaths with placeholder and then checking strings, make use of the functions
relocate.is_recocatable and relocate.is_file_relocatable to decide if a package needs the allow-root option.

This fixes a problem where the placeholder path was not in the first rpath entry. This was seen in c++ libraries and binaries because the compiler was outside the spack install base path and always appears first in the rpath.

Instead of checking the first rpath entry, all rpaths have the placeholder path and the old install path (if it exists) replaced with the new install path.

The second commit changes the check for old install path strings by using the install prefix instead of the install root.
gartung added a commit to gartung/spack that referenced this pull request Mar 1, 2019
…unctions introduced in

spack#9199

Instead of replacing rpaths with placeholder and then checking strings, make use of the functions
relocate.is_recocatable and relocate.is_file_relocatable to decide if a package needs the allow-root option.

This fixes a problem where the placeholder path was not in the first rpath entry. This was seen in c++ libraries and binaries because the compiler was outside the spack install base path and always appears first in the rpath.

Instead of checking the first rpath entry, all rpaths have the placeholder path and the old install path (if it exists) replaced with the new install path.
@alalazo alalazo deleted the features/buildcache_preview branch March 1, 2019 06:09
gartung added a commit that referenced this pull request Mar 1, 2019
…rpath entry.

* Rework of buildcache creation and install prefix checking using the functions introduced in
#9199

Instead of replacing rpaths with placeholder and then checking strings, make use of the functions
relocate.is_recocatable and relocate.is_file_relocatable to decide if a package needs the allow-root option.

This fixes a problem where the placeholder path was not in the first rpath entry. This was seen in c++ libraries and binaries because the compiler was outside the spack install base path and always appears first in the rpath.

Instead of checking the first rpath entry, all rpaths have the placeholder path and the old install path (if it exists) replaced with the new install path.

* flake8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show to user which packages might be relocated

5 participants