From 89fc75d5d35cc0c700a25ddb321143ca15fb70dc Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 4 Jun 2019 15:13:53 +0200 Subject: [PATCH] docs: Initial vendoring documentation Signed-off-by: Samuel Ortiz --- docs/vendoring.md | 85 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs/vendoring.md diff --git a/docs/vendoring.md b/docs/vendoring.md new file mode 100644 index 000000000..939da402e --- /dev/null +++ b/docs/vendoring.md @@ -0,0 +1,85 @@ +# Cloud Hypervisor vendoring + +The `cloud-hypervisor` build relies on having all dependencies locally vendored, +for several reasons: + +1. Reproducible builds: Separate builds from the same cloud-hypervisor git + commit will build against exactly the same set of dependencies. + +1. Network isolated builds: Vendoring allows us to build cloud-hypervisor + in a network isolated environment. All dependencies are locally fetched + and thus `cargo` will not try to fetch crates from external repositories. + +1. Simplified custom dependencies: When having to deal with custom, temporary + dependencies, vendoring allows for a centralized and simple way of overriding + an existing dependency with a custom one. + +## Workflow + +The `cargo vendor` tool does 2 things: + +1. It generates vendored copies of all dependencies that the project crates + describe through their `Cargo.toml` files. + +1. It creates a `.cargo/config` amendment to force cargo builds to use the + vendored copies instead of the external ones. + +It's important to note that `cargo vendor` can not force a dependency version +or revision. All dependencies are described through the project crates +`Cargo.toml` files. + +As a consequence, vendoring and dependency revision pinning are 2 separate +things, and `cargo vendor` only handles the former. + +All the `cloud-hypervisor` vendored dependencies are under the `vendor` +directory. For all intents and purposes the `vendor` directory is read-only and +should not be manually modified. + +The sections below describe a few vendoring use cases: + +### Overriding a crates.io dependency + +For overriding a `crates.io` crate with a local or remote crate, we first need +to modify the project's top-level `Cargo.toml` file. + +For example, if we want to switch from the `crates.io` `kvm-ioctls` package to +a forked one containing some specific feature or fix we would add the following +lines to the project top-level `Cargo.toml` file: + +```toml +[patch.crates-io] +kvm-ioctls = { git = "https://github.com/sboeuf/kvm-ioctls", branch = "kvm_signal_msi" } + +``` + +Then we need to vendor that change: + +```shell +cargo vendor --relative-path --no-merge-sources ./vendor > .cargo/config +``` + +### pinning a git dependency + +Some crates may depend on non published crates, that are developed and +maintained in some git repository. + +Let's take the `vm-memory` crate as one example. It is a `rust-vmm` crate that +is not yet published in `crates.io`. Several `cloud-hypervisor` crates depend +on it. Provided that none of those dependent crates rely on a specific branch +or revision of the `vm-memory` crate, we may want to pin our project to the +crate revision `281b8bd6cd2927f7a65130194b203a1c2b0ad2e3`. + +We need to describe that revision pin and then vendor it. First we need to add +the following lines to the project top-level `Cargo.toml`: + +```toml +[dependencies.vm-memory] +git = "https://github.com/rust-vmm/vm-memory" +rev = "281b8bd6cd2927f7a65130194b203a1c2b0ad2e3" +``` + +And then vendor that change: + +```shell +cargo vendor --relative-path --no-merge-sources ./vendor > .cargo/config +```