Skip to content

Bugfix/mirror symlinks#13908

Merged
alalazo merged 6 commits intospack:developfrom
scheibelp:bugfix/mirror-symlinks
Dec 13, 2019
Merged

Bugfix/mirror symlinks#13908
alalazo merged 6 commits intospack:developfrom
scheibelp:bugfix/mirror-symlinks

Conversation

@scheibelp
Copy link
Copy Markdown
Member

@scheibelp scheibelp commented Nov 27, 2019

(update 12/4: this PR should be rebased the commits apply fixes for thematically-related but functionally-separate problems, and I intend that the commits are properly-formatted and organized for that)

Fixes #13722 (or rather addresses the parts of it that were not addressed by #13789)
Fixes #14067
Closes #14093

  • Don't try to fetch BundlePackages
  • Don't fetch patches if they were already added to the mirror
  • Bugfix/mirror all patch conflicts #13789 started calculating a relative path, relative to another relative path. This can fail based on the working directory, so the intended reference point for the relative path is created explicitly as the absolute path
  • Allow repeated invocations of spack mirror create on the same mirror directory (in develop this currently reports errors)

@scheibelp
Copy link
Copy Markdown
Member Author

scheibelp commented Dec 5, 2019

@tgamblin this particular PR should be rebased (vs. squashed): I have formatted all the commit messages.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Dec 10, 2019

this particular PR should be rebased (vs. squashed): I have formatted all the commit messages.

Question related to commit messages: can you add a handle to this PR in each commit if this is not squashed? Asking because it's quite useful when you read code to annotate it and eventually read the PRs associated with the lines of interest.

@sknigh
Copy link
Copy Markdown

sknigh commented Dec 10, 2019

@scheibelp I don't know if the other PRs fix the long timeout issue, but I tweaked this branch to get a better behavior. I added --connect-timeout to the curl arguments. It only exits when an initial connection cannot be established within a 15 second limit.

diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index 409cc334e..a6956b7d4 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -324,6 +324,7 @@ def fetch(self):
             '-D',
             '-',  # print out HTML headers
             '-L',  # resolve 3xx redirects
+            '--connect-timeout', '15',
             self.url,
         ]
 
diff --git a/lib/spack/spack/mirror.py b/lib/spack/spack/mirror.py
index ceb53801c..3a863188a 100644
--- a/lib/spack/spack/mirror.py
+++ b/lib/spack/spack/mirror.py
@@ -499,7 +499,7 @@ def add_single_spec(spec, mirror_root, mirror_stats):
     tty.msg("Adding package {pkg} to mirror".format(
         pkg=spec.format("{name}{@version}")
     ))
-    num_retries = 3
+    num_retries = 1
     while num_retries > 0:
         try:
             with spec.package.stage as pkg_stage:

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Dec 10, 2019

@sknigh See #13881 for a PR that adds the same flag.

@scheibelp scheibelp force-pushed the bugfix/mirror-symlinks branch from 4f47842 to d7e6557 Compare December 11, 2019 02:10
@alalazo alalazo added the bugfix Something wasn't working, here's a fix label Dec 11, 2019
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.

I have one minor question on broken links. Waiting for that before merging this.

@scheibelp scheibelp force-pushed the bugfix/mirror-symlinks branch from d7e6557 to abe5d9a Compare December 12, 2019 03:01
@scheibelp
Copy link
Copy Markdown
Member Author

scheibelp commented Dec 12, 2019

(EDIT 12/12: some of this is incorrect and has been corrected by #13908 (comment))

This is failing because as part of addressing #13908 (comment) I invoke os.remove on the symlink which actually deletes the file that it points to. Oddly os.unlink appears to fail in this way also, so I'm not sure if there is a way to remove the symlink properly.

I can either:

  • hack the ability to delete symlinks for existing files into Spack (e.g. by temporarily moving the symlink target to a temporary directory)
  • examine the link but never delete it (and inform the user of the issue)

The latter does not seem very reasonable to me so I'll be thinking about how to do the first one.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Dec 12, 2019

@scheibelp I think os.unlink does what you want on linux (remove the link without deleting what it points to) but:

  1. The documentation contradicts the current behavior (it says it has the same semantic a os.remove which is not always true)
  2. The behavior might be OS/platform specific

Another alternative might be to return early if the link os.exists:

if os.path.exists(cosmetic_path):
    return

which means it's not broken (so basically rule out every exception to the happy code path at the beginning of the method).

@scheibelp
Copy link
Copy Markdown
Member Author

Thanks for the suggestion!

I think os.unlink does what you want on linux

I encountered this problem on Mac OS so that might be why it comes up for me

Another alternative might be to return early if the link os.exists:

I agree that checking both os.path.lexists and os.path.exists should resolve the issue for all platforms. I'll be able to fix that this evening.

When creating a cosmetic symlink for a resource in a mirror, remove
it if it already exists. The symlink is removed in case the logic to
create the symlink has changed.
The targets for the cosmetic paths in mirrrors were being calculated
incorrectly as of fb3a3ba: the symlinks used relative paths as targets,
and the relative path was computed relative to the wrong directory.
Since cache_mirror does the fetch itself, it also needs to do the
checksum itself if it wants to verify that the source stored in the
mirror is valid. Note that this isn't strictly required because fetching
(including from mirrors) always separately verifies the checksum.
When updating a mirror, Spack was re-retrieving all patches (since the
fetch logic for patches is separate). This updates the patch logic to
allow the mirror logic to avoid this.
BundlePackages use a noop fetch strategy. The mirror logic was assuming
that the fetcher had a resource to cach after performing a fetch. This adds
a special check to skip caching if the stage is associated with a
BundleFetchStrategy. Note that this should allow caching resources
associated with BundlePackages.
@scheibelp scheibelp force-pushed the bugfix/mirror-symlinks branch from abe5d9a to 7ba1d0e Compare December 12, 2019 21:58
@scheibelp
Copy link
Copy Markdown
Member Author

#13908 (comment) worked for me but to clarify:

I asserted in #13908 (comment) that os.unlink was deleting the target of a symlink. That's not true: it turns out some tests were creating a file vs. a symlink at cosmetic_path, and os.unlink will delete the provided path if it refers to a file (vs. a symlink), which was causing the error.

So at this point all requests are addressed.

@alalazo alalazo merged commit 8c2305e into spack:develop Dec 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Something wasn't working, here's a fix fetching

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spack mirror create creates broken symlinks Error when creating mirror in already existing mirror location

4 participants