Skip to content

Feature: add option to create view by copying/relocating files#16480

Merged
becker33 merged 11 commits intodevelopfrom
features/view-copy
Jun 3, 2020
Merged

Feature: add option to create view by copying/relocating files#16480
becker33 merged 11 commits intodevelopfrom
features/view-copy

Conversation

@becker33
Copy link
Copy Markdown
Member

@becker33 becker33 commented May 5, 2020

Views can currently be created by symlinks or hardlinks. In both cases, dependencies are silently used from the original location.

In deployment contexts, this can cause permissions problems if one user installs a package and creates a public view for other users.

The spack view copy subcommand is an alternative that copies files into place, using logic from lib/spack/spack/relocate.py to edit the files in the new location to point to each other.

TODO:

  • tests

@becker33 becker33 force-pushed the features/view-copy branch 2 times, most recently from 2d0c818 to 34c12bf Compare May 5, 2020 23:57
@becker33 becker33 force-pushed the features/view-copy branch from 247010e to 20b030e Compare May 8, 2020 18:37
@becker33
Copy link
Copy Markdown
Member Author

Closing-bouncing to restart tests.

@becker33 becker33 closed this May 14, 2020
@becker33 becker33 reopened this May 14, 2020
Copy link
Copy Markdown
Member

@alalazo alalazo left a comment

Choose a reason for hiding this comment

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

Mostly LGTM. The only requested change is that spack view remove doesn't fail on relocated trees. Also left a few other style comments, let me know if you disagree with anything.

Comment on lines +52 to +87
def view_copy(src, dst, view, spec):
shutil.copyfile(src, dst)
if spec:
# Not metadata, we have to relocate it

# What type of file are we relocating
relocate_method = spack.relocate.relocate_text_bin \
if spack.relocate.is_binary(dst) else spack.relocate.relocate_text

# Get information on where to relocate from/to
prefix_to_prefix = dict(
(dep.prefix, view.get_projection_for_spec(dep))
for dep in spec.traverse()
)

# Call actual relocation method
relocate_method(
[dst], spack.store.layout.root, view._root,
spec.prefix, view.get_projection_for_spec(spec),
spack.paths.spack_root, view._root, prefix_to_prefix
)
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.

Relocation might take some time. Since this function doesn't prompt anything up to completion, relocating a package might give users the feeling Spack is hanging:

$ time spack view relocate ~/tmp/spack-relocate netlib-scalapack

real    0m25,616s
user    0m18,356s
sys     0m7,839s

Comment on lines +75 to +79
def view_link_wrapper(view, link_method):
def view_link(src, dst, spec=None):
link_method(src, dst, view, spec)

return view_link
Copy link
Copy Markdown
Member

@alalazo alalazo May 19, 2020

Choose a reason for hiding this comment

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

We can probably use functools.partial instead of this wrapper.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This proved tricky, because of the way the wrapper was setting the default for the spec argument (which can't be set in the function signature, because view is a mandatory argument.

I couldn't swap the order, because then the keyword argument view comes before the argument spec once I call functools.partial.

The only thing that worked was to make both into keyword arguments. I'm perfectly okay with that, and I've done so.

Comment on lines +27 to +28
@pytest.mark.parametrize('cmd', ['hardlink', 'symlink', 'hard', 'add',
'copy', 'relocate'])
Copy link
Copy Markdown
Member

@alalazo alalazo May 19, 2020

Choose a reason for hiding this comment

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

Can we rework the test to receive an additional parametrized value is_link:

Suggested change
@pytest.mark.parametrize('cmd', ['hardlink', 'symlink', 'hard', 'add',
'copy', 'relocate'])
@pytest.mark.parametrize('cmd,is_link', [
('hardlink', False),
('symlink', True),
('hard', False),
('add', True),
('copy', False),
('relocate', False)
])

? In my opinion that would be clearer than (cmd in ('symlink', 'add'))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I used a different method that I felt was cleaner to make this clearer, let me know if that works for you.

Copy link
Copy Markdown
Member

@alalazo alalazo left a comment

Choose a reason for hiding this comment

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

Travis is failing because in the current implementation spec and view should be strings when used as keys for kwargs. That said, I think you can avoid having to use kwargs at all if you give default values to spec in the signature.

@becker33 becker33 force-pushed the features/view-copy branch from 3c91c86 to 19e11cb Compare June 2, 2020 23:49
@becker33
Copy link
Copy Markdown
Member Author

becker33 commented Jun 3, 2020

@alalazo had to rebase this to account for your changes to relocate.py in the interim.

Copy link
Copy Markdown
Member

@alalazo alalazo left a comment

Choose a reason for hiding this comment

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

The spack view copy command works as intended, and code LGTM. There are several issues with spack view remove that are very likely not related to this PR. I'll post a comment below the review, but imo we can merge this as it is and fix spack view remove in another PR.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Jun 3, 2020

I saw a couple of issues while trying the spack view remove command. These are probably not related to this PR and can be fixed in a following one. The first issue is that copy tree are not removed completely:

$ tree -L 2 spack-view
spack-view
├── copy
├── hardlink
└── symlink
$ spack view copy spack-view/copy hdf5
$ tree -L 2 spack-view
spack-view
├── copy
│   ├── bin
│   ├── include
│   ├── lib
│   └── share
├── hardlink
└── symlink

7 directories, 0 files
$ spack view remove -a spack-view/copy
$ tree -L 2 spack-view
spack-view
├── copy
│   ├── bin
│   └── lib
├── hardlink
└── symlink

The second issue is that hardlink trees fail to be removed:

$ tree -L 2 spack-view
spack-view
├── copy
├── hardlink
└── symlink
$ spack view hardlink ~/tmp/spack-view/hardlink hdf5
$ tree -L 2 spack-view
spack-view
├── copy
├── hardlink
│   ├── bin
│   ├── include
│   ├── lib
│   └── share
└── symlink

$ spack view remove ~/tmp/spack-view/hardlink hdf5
==> Error: [Errno 2] No such file or directory: '/home/culpo/tmp/spack-view/hardlink/lib/libhdf5.so.103'

symlink trees seem instead to work properly and be completely removed.

@becker33 becker33 merged commit 3347ef2 into develop Jun 3, 2020
@alalazo alalazo deleted the features/view-copy branch June 3, 2020 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants