-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
Restore osx cache #14485
Restore osx cache #14485
Conversation
.circleci/config.yml
Outdated
- /usr/local/Cellar/boost | ||
- /usr/local/Cellar/cmake | ||
- /usr/local/Cellar/wget | ||
- /usr/local/Cellar/coreutils | ||
- /usr/local/Cellar/diffutils |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it's really safe to do it like this. If you do not restore it all, we end up with some bits coming from cached homebrew and some coming from the image. What are the parts you are not caching?
This does seem to pass tests and gives a nice speedup so I'm a bit torn on this. Caching the whole /usr/local/Cellar
and /usr/local/Homebrew
like we used to seems like it would be less prone to break in weird ways at some point in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly don't know if it is safe to do this way, but I decided to cache only what we need because if we cache everything inside the Cellar
directory, it actually does not save us time. Restoring the cache ends up being slower (for example, see: https://app.circleci.com/pipelines/github/r0qs/solidity/640/workflows/b7416bf3-b054-48a1-ada1-d89c8e047a95/jobs/19678)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if we first remove everything from /usr/local/Cellar
before restoring? My impression is that the slowdown really comes from printing all those errors (or maybe it's that just handling them goes through some horribly inefficient code path in tar
?). It used to be pretty fast back when we used to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if we first remove everything from
/usr/local/Cellar
before restoring?
Hum...not sure if this would be the best way, since it would attempt to install/update all the packages twice in the first run (when there is no cache available). Also, it would cause errors like this: https://app.circleci.com/pipelines/github/ethereum/solidity/30938/workflows/1d8b9f77-a106-47a3-91d7-d561b4cfe8d2/jobs/1375906, i.e. some commands will not be available until we reinstall everything. I would rather just keep it as it is now, i.e. caching and restoring only the packages we need.
My impression is that the slowdown really comes from printing all those errors (or maybe it's that just handling them goes through some horribly inefficient code path in
tar
?). It used to be pretty fast back when we used to do that.
Yes, I have the same impression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, it would cause errors like this
But isn't that because you do not recreate an empty directory after deleting it?
it would "install" the packages in the
Cellar
twice in the first run
What's the problem with that? It's fine if the first run is longer as long as it's not extremely so. We update macOS dependencies quite rarely so the cache will almost always be present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, it would cause errors like this
But isn't that because you do not recreate an empty directory after deleting it?
No, I was referring to this error here:
/Users/distiller/.bash_profile: line 19: rbenv: command not found
/Users/distiller/.bash_profile: line 22: pyenv: command not found
Running `brew update --auto-update`...
I copied the wrong link in the previous comment: https://app.circleci.com/pipelines/github/ethereum/solidity/30938/workflows/1d8b9f77-a106-47a3-91d7-d561b4cfe8d2/jobs/1375906?invite=true#step-105-0_65
it would "install" the packages in the
Cellar
twice in the first runWhat's the problem with that? It's fine if the first run is longer as long as it's not extremely so. We update macOS dependencies quite rarely so the cache will almost always be present.
Well, I suspect it will be almost twice the time that it is currently, which is around 5 minutes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied the wrong link in the previous comment: https://app.circleci.com/pipelines/github/ethereum/solidity/30938/workflows/1d8b9f77-a106-47a3-91d7-d561b4cfe8d2/jobs/1375906?invite=true#step-105-0_65
Looks like the same link to me, just an extra anchor.
Well, I suspect it will be almost twice the time that it is currently, which is around 5 minutes.
That would be bad if we had to do it on every run, but still acceptable if it only runs rarely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied the wrong link in the previous comment: https://app.circleci.com/pipelines/github/ethereum/solidity/30938/workflows/1d8b9f77-a106-47a3-91d7-d561b4cfe8d2/jobs/1375906?invite=true#step-105-0_65
Looks like the same link to me, just an extra anchor.
Yes, this is what I meant haha
Well, I suspect it will be almost twice the time that it is currently, which is around 5 minutes.
That would be bad if we had to do it on every run, but still acceptable if it only runs rarely.
Ok, if you think it is acceptable, I will do the change then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is what I meant haha
Ah, it was a link to a specific line in the output? Didn't even know you could do that :) I did not notice and just scrolled immediately to the end of output by habit :)
In any case, isn't .bash_profile
only for interactive sessions? Not really sure why it would need rbenv
and pyenv
there. Is their macOS env really using Ruby and Python installed somewhere in user's profile via those instead of the global interpreters?
I see that homebrew is immediately installing its own portable Ruby. I wonder if it's because of that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is what I meant haha
Ah, it was a link to a specific line in the output? Didn't even know you could do that :) I did not notice and just scrolled immediately to the end of output by habit :)
haha yes, the first two lines of the Install build dependencies
step.
In any case, isn't
.bash_profile
only for interactive sessions?
Yeah, as far as I know it is loaded during login. So I imagine that when the circleci user logins in the container to run the commands it also loads the .bash_profile
of that user.
Not really sure why it would need
rbenv
andpyenv
there. Is their macOS env really using Ruby and Python installed somewhere in user's profile via those instead of the global interpreters?
I'm not sure either, as I don't use macOS. But there are some environment variables for pyenv and rbenv that are set by default in the circleci macOS image, i.e. : PYENV_SHELL=bash
and RBENV_SHELL=bash
.
I see that homebrew is immediately installing its own portable Ruby. I wonder if it's because of that?
Yeah, it could be.
e8af597
to
81438b1
Compare
942c70d
to
9a910f7
Compare
I just got a different idea. How about caching not the installed dir but the binary packages that Homebrew downloads? Then it would still install them but that should be quick. There are some suggestions on how to do that here: How to use Homebrew to install local archive. Actually, maybe caching only |
Also, does homebrew touch |
But the homebrew packages are already cached when we cache the
Yes, but it needs the correspondent
But yeah, I'm not sure if this is the correct way to cache a homebrew package, since I'm not a macOS user.
UPDATE: the |
.circleci/config.yml
Outdated
- /usr/local/opt | ||
- /usr/local/share | ||
- /usr/local/var |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just realized that homebrew install more things that if not cached may indeed break the image. You can check it running the brew doctor
command in the container.
Warning: Some installed formulae are missing dependencies.
You should `brew install` the missing dependencies:
brew install ca-certificates gettext gmp icu4c libidn2 libunistring lz4 [email protected] xz zstd
Run `brew missing` for more details.
static:Cellar distiller$ brew missing
boost: icu4c xz lz4 zstd
coreutils: gmp
wget: gettext libunistring libidn2 ca-certificates [email protected]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far, the only way that I could make it work was not deleting the whole Cellar
directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is /usr/local/var
as volatile as /var
? Caching /var
would go way beyond what I'd call reasonable :)
Overall, looks like this is not the way to go. Too many assumptions about what Homebrew is doing. We need something more robust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I added that only for testing, attempting to fix the errors reported by the brew doctor
. Upon further look, it turned out that the important directory there is only /usr/local/var/homebrew
which contains symlinks to the respective files under the Cellar
directory.
516c52b
to
445a48a
Compare
But I meant only caching the binary packages which Homebrew uses to install things. I.e. we would cache I was just not sure if caching Seeing the issues you're running into, I really think this is the right way forward here. We could do this for evmone, z3 and jsoncpp as well - basically only cache the |
But I meant the opposite :) I.e. that if Homebrew does not touch them then we can safely cache them independently, to reenable caching at least for evmone, z3 and jsoncpp, even if we don't manage to do it for Homebrew. But apparently it does use these dirs? In any case, I'd rather try with the solution I posted above, which should be much less messy. Also, perhaps we should shelve this for now and go back to it later. I thought it would be useful to try to reenable the cache and see if it works, but we're way beyond that. This was meant to be quick and easy :P |
Right. Just to add more context, the files are installed in the
The binary packages that homebrew use to install things are in the
We could try to force install from a local bottle using:
Because everything in
So I don't see a way to not cache the
Yes, got distracted by the homebrew errors and forgot about those other packages, for those we will need to cache the |
Why not cache only the downloaded archive like I suggested?
What happens if you try without The way I'm suggesting is this:
|
Because
Yes, indeed. However, in all tests that I tried, even if the package exists in the homebrew's cache but it does not exists in the
I believe that for this we can use the Also, having the formula does not help too much I think, since the formula only specify how the package will be installed and does not really contain the necessary files to install it, see for example the wget formula. |
ec35d2d
to
8996ae2
Compare
I mean, I think we should cache only the archives. This makes things simpler because you don't have to worry about some random stuff being in the directories we would otherwise have to cache. Downloading the binaries is the slow part. Installation is quick, so we can just repeat it every time.
I'd not cache the formulas. I think they should be redownloaded each time. This is because we need a way to know if cache is up to date or not. We can only know that by looking at what the latest versions of the packages are and I assume that homebrew will by default download the latest version of the formula and we'll see the version inside. If any package has been updated, we invalidate the cache, run installation from scratch and cache it. But for that I'm assuming homebrew must have some command that just downloads the formula independently of the binary packages. Alternatively, maybe it has a command that tells us the latest version of a formula. If it does not, the last resort would be to download the formula manually with wget or git. |
This pull request is stale because it has been open for 14 days with no activity. |
This pull request was closed due to a lack of activity for 7 days after it was stale. |
Fix #12925.