-
Notifications
You must be signed in to change notification settings - Fork 28
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
switch to fixed directory for twoliter tools #102
Conversation
let tempdir = tools_tempdir()?; | ||
install_tools(&tempdir).await?; | ||
let makefile_path = tempdir.path().join("Makefile.toml"); | ||
let toolsdir = project.project_dir().join("build/tools"); |
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.
Maybe the project object should provide such things (build_dir, tools_dir, etc)
let toolsdir = project.project_dir().join("build/tools"); | |
let toolsdir = project.tools_dir(); |
twoliter/src/cmd/make.rs
Outdated
let makefile_path = tempdir.path().join("Makefile.toml"); | ||
let toolsdir = project.project_dir().join("build/tools"); | ||
let _ = std::fs::remove_dir_all(&toolsdir); | ||
std::fs::create_dir_all(&toolsdir)?; |
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.
Use tokio
. Also I don't think even tokio
gives a helpful error message. I have planned to add this to common.rs
for convenience. The idea would be to move error message creation somewhere else.
mod fs {
pub(crate) async fn create_dir_all(path: impl AsRef<Path>) -> Result<()> {
tokio::fs::create_dir_all(path.as_ref()).context(format!("Unable to create directory '{}'", path.as_ref().display());
}
}
@@ -34,9 +33,11 @@ pub(crate) struct Make { | |||
impl Make { | |||
pub(super) async fn run(&self) -> Result<()> { |
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.
@ecpullen these are changes to the code that you are moving.
// Write out the embedded tools and scripts. | ||
unpack_tarball(&dir) | ||
.await | ||
.context("Unable to install tools")?; | ||
|
||
// Pick one of the embedded files for use as the canonical mtime. |
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.
Why do we need a canonical mtime? Is this preventing docker rebuilds?
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.
Why do we need a canonical mtime? Is this preventing docker rebuilds?
I'll add a comment to the code. It's a minor optimization to make the build context more efficient by not always copying the tools through.
For example on a local build with a 180 MiB file:
❯ docker build --progress=plain .
...
#10 [internal] load build context
#10 sha256:8fe1ebd2168d7202972f3fed513e650e6bc14c1252ef426d770005b1b769b70b
#10 transferring context: 183.54MB 0.5s done
#10 DONE 0.6s
❯ docker build --progress=plain .
...
#10 [internal] load build context
#10 sha256:942722aa20dadaa1f21a60c65ffa04d801e48ac344603e42b368fda45457366a
#10 transferring context: 291B done
#10 DONE 0.0s
❯ touch -r Dockerfile NVIDIA-Linux-aarch64-470.82.01.run
❯ docker build --progress=plain .
...
#10 [internal] load build context
#10 sha256:8fe1ebd2168d7202972f3fed513e650e6bc14c1252ef426d770005b1b769b70b
#10 transferring context: 183.54MB 0.5s done
#10 DONE 0.6s
❯ docker build --progress=plain .
...
#10 [internal] load build context
#10 sha256:ec46d1475e765e302cc924f8682c05c897c1a56df7a3b356bae7b1b866eb4c74
#10 transferring context: 291B done
#10 DONE 0.0s
The build context is more intelligent than a Docker layer in the sense that modifying a single file results in only that file being transferred, not the entire build context. But it still seems worth avoiding unnecessary copies.
The direction I'm exploring with passing file descriptors could let us get rid of all the changes to the build context. /packages/*/*.tar.*
, /build/rpms
, /.gomodcache
, and /.cargo
are the current offenders. I'd like to avoid others.
@@ -20,12 +20,14 @@ fn main() { | |||
let paths = Paths::new(); | |||
println!("cargo:rerun-if-changed={}", paths.data_input_dir.display()); | |||
|
|||
let _ = fs::remove_dir_all(&paths.prep_dir); |
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.
If we can avoid updating build.rs, that would be great. The entire file will be changed in an upcoming pr.
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.
If we can avoid updating build.rs, that would be great. The entire file will be changed in an upcoming pr.
The addition of a file appears to be necessary for this PR, that is Dockerfile.dockerignore
, so at least one change in build.rs
is not optional. Anyway, the changes here should be easy to replay. Delete the prep dir and add a file.
c05d9e1
to
c08da4c
Compare
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 can follow up with some of the refactoring things I mentioned.
c08da4c
to
c0ef5c4
Compare
Secrets have a maximum size of 500 KiB, which is not sufficient to pass binaries to the build. This would prevent us from using native code rather than shell scripts. Install the tools into `build/tools` instead, taking care to clean up any previous installs and to reset the file modification times so as not to bust any caches or trigger unnecessary rebuilds. Signed-off-by: Ben Cressey <bcressey@amazon.com>
This leaves an empty build directory when `cargo make clean` runs. Signed-off-by: Ben Cressey <bcressey@amazon.com>
Signed-off-by: Ben Cressey <bcressey@amazon.com>
The build system has very specific requirements on what to include in the Docker build context in order to work as expected. Embedding the file avoids the need for a synchronized change in other projects when updating Twoliter. Signed-off-by: Ben Cressey <bcressey@amazon.com>
Otherwise, files that were present in an earlier build that have been renamed or removed might still be in the prep directory, where they will be added to the new archive. Signed-off-by: Ben Cressey <bcressey@amazon.com>
c0ef5c4
to
d7aba25
Compare
Rebased (twice because of a mistake): |
@@ -1,9 +1,10 @@ | |||
use crate::cargo_make::CargoMake; | |||
use crate::project; | |||
use crate::tools::{install_tools, tools_tempdir}; | |||
use crate::project::{self}; |
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.
use crate::project::{self}; | |
use crate::project; |
I am merging this. I've been bitten for days with |
Issue #, if available:
N/A
Description of changes:
I've been experimenting with a tool to forward file descriptors into a build, which requires the ability to run something larger than a shell script during the Docker execution. That hits the limitation of secrets which can't be larger than 500 KiB.
Switching to a fixed install location under
build/tools
avoids this limitation and makes the code a bit more intuitive. It's also relatively easy to see whattwoliter
has installed.Because the tools need to be passed in the build context, I've also imported the current
.dockerignore
file from the core repo and renamed it toDockerfile.dockerignore
, so that it will be used by the BuildKit backend.Testing done:
Built some variants successfully. I also confirmed through various hacks that the
.dockerignore
file was being respected. For example, excluding/build/rpms/*.rpm
caused the expected build failure.Terms of contribution:
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.