Skip to content

Fsview extensions#5415

Merged
scheibelp merged 33 commits intospack:developfrom
mathstuf:fsview_extensions
Nov 3, 2017
Merged

Fsview extensions#5415
scheibelp merged 33 commits intospack:developfrom
mathstuf:fsview_extensions

Conversation

@mathstuf
Copy link
Copy Markdown
Contributor


This is a rebase of #3227 that should be a lot easier to review. Basically, extension availability for views is now computed based on the view itself rather than looking globally.

Cc: @scheibelp

@healther
Copy link
Copy Markdown
Contributor

We are aware of an usability problem with the current state of #3227 due to the fact that some packages ship their own version of required libraries in the same position as "system" libraries.

One example is llvm which provides its own lib/python2.7/site-packages/six.py which conflicts with the lib/python2.7/site-packages/six.py from py-six. When adding both llvm and py-six to the same view these files collide.
In the current state of #3227 this ends in an exception and the rest of the linking is aborted. As the "list "of packages to add is actually a set, the order of the linking is not guaranteed and we ended up adding an ignore-all-conflicts-by-skipping-existing-packages flag to the spack view add parser. Unfortunately we haven't managed to put that in #3227 yet.

We also thought about implementing some smarter version, i.e. deciding automatically whether to replace, skip or merge two files. However llvm/six.py and py-six/six.py where identical only up to formatting. So here it would have been save to choose either one, but we were uncomfortable with an automatic solution, as the content of the two files where not identical.
So we avoided the problem by just ignoring it and telling the people using it: Keep your eyes open, there might be inconsistent dependencies in this view. So far we haven't had any complaints...

cc @obreitwi

@mathstuf
Copy link
Copy Markdown
Contributor Author

LLVM should vendor it's six.py install to not conflict. That is a bug with LLVM that should be addressed.

@scheibelp
Copy link
Copy Markdown
Member

There appears to be enough support for ignoring conflicts that the view command would only need to add an --ignore-conflicts option; there appears to even be some code which looks for this option. When it's enabled it would print warnings when paths conflict (instead of failing).

@healther
Copy link
Copy Markdown
Contributor

If I recall correctly that only handled the "loading" of packages correctly but not the "activation" of packages

@mathstuf
Copy link
Copy Markdown
Contributor Author

mathstuf commented Oct 5, 2017

I've added code which:

  • fixes spack extensions listing of installed packages: it was just listing activated packages;
  • the extensions, activate, and deactivate commands now take a --view (or -v) argument to operate on a view; and
  • spack extensions --show <packages|installed|activated|all> is now implemented.

yield spec.package
except spack.directory_layout.NoSuchExtensionError:
continue
# TODO: conditional way to do this instead of catching exceptions
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why is catching exceptions a bad idea?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is copied from the old implementation. I imagine what is wanted is that instead of throwing an exception when a package doesn't extend a given spec is to return False or some other well-typed return value instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah sorry, I mistook the code position. I actually have no idea where this comes into play. However in general I prefer python code that indicates violated assumptions by exceptions instead of using a special invalid marker of the normal return value. I'm not too sure why the exception is caught in the first place (and especially swallowed without a logged event..)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Looking at the code that does this, it really should return a bool. Currently it throws or it doesn't.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

And this code doesn't need the catch, it is check_activated that does the weird control flow.

@mathstuf mathstuf force-pushed the fsview_extensions branch 3 times, most recently from 41739ab to 237578d Compare October 13, 2017 15:29
@mathstuf
Copy link
Copy Markdown
Contributor Author

I found the bit which needed fixed for testing to work (a new variable added on this PR needed mocked out as well). Seems I need to fix some Python3 issues.

@mathstuf mathstuf force-pushed the fsview_extensions branch 3 times, most recently from 19a0ec0 to 8c3bf45 Compare October 18, 2017 18:26
@mathstuf
Copy link
Copy Markdown
Contributor Author

Fixed the Python3 error. The YAML dumper needed to be told what encoding to use explicitly.


set(map(self._check_no_ext_conflicts, extensions))
# fail on first error, otherwise link extensions as well
if all(map(self.add_standalone, standalones)):
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.

I'm starting to look at this now. I noticed if one of the packages is external and has a prefix like:

packages:
    openssl:
        paths:
            [email protected]: /usr/local

That all of /usr/local will be added. Could you add a check to skip external specs here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ew, yeah, I'll do that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK, fixed and I've added a test for it.

Copy link
Copy Markdown
Member

@scheibelp scheibelp left a comment

Choose a reason for hiding this comment

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

I have a couple requests:

  • Expanded testing: I specifically mention in comments what I think would be worthwhile. To be clear my goal is not to meet the percent threshold to get a check
  • Be more strict when looking for globally-activated packages in view.view

Let me know if these suggestions seem off track.

# status and remove can map the name to packages in view
specs = relaxed_disambiguate(args.specs, view)

activated = list(filter(lambda s: s.package.is_extension and
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.

The main goal of collecting these is to avoid a case where an extendee package has globally activated extensions and we add it to the view. I think a stronger check here would be to grab the extendee package and check activated_extensions_for. This would also mean changing the checks in test_view_extension_global_activation.

install('[email protected]')
install('[email protected]')
viewpath = str(tmpdir.mkdir('view'))
view('symlink', viewpath, '[email protected]')
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.

IMO it is also worth confirming that the files in the extension1 package were created in the view prefix.

# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack.main import SpackCommand
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.

Could you add a test for removing extensions from views?

IMO it would also be useful to add a test for a file conflict (two different packages have the same file and are added to a view).

@mathstuf
Copy link
Copy Markdown
Contributor Author

I fixed the symlinking an extendee with global activations and added the other tests as well.

@scheibelp
Copy link
Copy Markdown
Member

All changes appear good. However, I was looking through packages which implement activate and realized that perl still refers to spack.store.layout.extension_map. I'm not sure why it does because Package.activate already handles modifying the extension map, so I think the references can just be removed.

@mathstuf
Copy link
Copy Markdown
Contributor Author

Python does the same thing; I just coverted it over to using the same argument setup.

@scheibelp
Copy link
Copy Markdown
Member

scheibelp commented Oct 27, 2017

The aspell package is also extendable and implements activate in a way that only works for globals.

This may not matter though if aspell doesn't have a PYTHONPATH equivalent. @hartzell (as the contributor of Spack's aspell package definition) do you happen to know if it does?

@mathstuf
Copy link
Copy Markdown
Contributor Author

Not sure about aspell, but hunspell supports DICPATH. Looking at aspell source code, I don't see one.

extensions_layout = args.get("extensions_layout",
spack.store.extensions)
if extensions_layout is not spack.store.extensions:
raise ExtensionError(
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.

Also need to import ExtensionError

# - extension.prefix.lib instead of extension.prefix in LinkTree()
# - dest_dir instead of self.prefix in tree.(find_conflict|merge)()
def activate(self, extension, **kwargs):
extensions_layout = args.get("extensions_layout",
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.

args should be kwargs

tree.merge(dest_dir, ignore=ignore)

def deactivate(self, extension, **kwargs):
extensions_layout = args.get("extensions_layout",
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.

args should be kwargs

mathstuf and others added 4 commits November 2, 2017 17:17
Aspell compiles in the paths it looks for rather than looking relative
to its binary location. There are also no environment variables to
redirect it other than changing the path to the configuration file it
looks at.
This is used in tests to test real packages without actually building
and installing them.
@scheibelp
Copy link
Copy Markdown
Member

These test failures do not appear related to the edits so I am closing and reopening to restart tests.

@scheibelp scheibelp closed this Nov 3, 2017
@scheibelp scheibelp reopened this Nov 3, 2017
@scheibelp scheibelp merged commit 0f896e9 into spack:develop Nov 3, 2017
@scheibelp
Copy link
Copy Markdown
Member

@obreitwi thanks for your work on this!

@mathstuf thanks for the added work (including testing)!

@tgamblin FYI this is now merged

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Nov 3, 2017

Thanks everyone!

@obreitwi
Copy link
Copy Markdown
Member

obreitwi commented Nov 3, 2017

@scheibelp @mathstuf Thanks for getting this done!

for s in spack.store.db.installed_extensions_for(spec)]

if show_all:
print
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.

what was the idea here @mathstuf?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Uhh…probably either stray debugging (unlikely) or an incomplete/untested flag combination.

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.

6 participants