Skip to content

Commit

Permalink
Merge pull request #110 from OffchainLabs/gligneul/audit-m-01
Browse files Browse the repository at this point in the history
Fix Inconsistent Docker Image Naming
  • Loading branch information
gligneul authored Nov 22, 2024
2 parents 1b8f476 + 2ace743 commit f0fe7f2
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 25 deletions.
7 changes: 7 additions & 0 deletions .ci/build_and_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ if [ "$CFG_RELEASE_CHANNEL" == "nightly" ]; then
else
cargo build --locked
fi

cargo test

if [ "$(uname -s)" != "Darwin" ]; then
# The MacOS CI doesn't support Docker because of licensing issues, so only run them on Linux.
# Also, run the docker tests on a single thread to avoid concurrency issues.
cargo test -F docker-test -- --test-threads 1 docker
fi
1 change: 1 addition & 0 deletions main/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ version.workspace = true
repository.workspace = true

[features]
docker-test = []
nightly = []

[dependencies]
Expand Down
80 changes: 55 additions & 25 deletions main/src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ use crate::constants::TOOLCHAIN_FILE_NAME;
use crate::macros::greyln;
use crate::project::extract_toolchain_channel;

fn image_exists(cargo_stylus_version: &str) -> Result<bool> {
let image_name = format!("cargo-stylus-base:{}", cargo_stylus_version);
fn image_name(cargo_stylus_version: &str, toolchain_version: &str) -> String {
format!(
"cargo-stylus-base-{}-toolchain-{}",
cargo_stylus_version, toolchain_version
)
}

fn image_exists(image_name: &str) -> Result<bool> {
let output = Command::new("docker")
.arg("images")
.arg(image_name)
Expand All @@ -37,21 +43,19 @@ a reproducible deployment, or opt out by using the --no-verify flag for local bu
Ok(output.stdout.iter().filter(|c| **c == b'\n').count() > 1)
}

fn create_image(cargo_stylus_version: Option<String>, version: &str) -> Result<()> {
let cargo_stylus_version =
cargo_stylus_version.unwrap_or_else(|| env!("CARGO_PKG_VERSION").to_string());
if image_exists(&cargo_stylus_version)? {
fn create_image(cargo_stylus_version: &str, toolchain_version: &str) -> Result<()> {
let image_name = image_name(cargo_stylus_version, toolchain_version);
if image_exists(&image_name)? {
return Ok(());
}
let name = format!(
"cargo-stylus-base-{}-toolchain-{}",
cargo_stylus_version, version
println!(
"Building Docker image for Rust toolchain {}",
toolchain_version
);
println!("Building Docker image for Rust toolchain {}", version,);
let mut child = Command::new("docker")
.arg("build")
.arg("-t")
.arg(name)
.arg(image_name)
.arg(".")
.arg("-f-")
.stdin(Stdio::piped())
Expand All @@ -60,32 +64,28 @@ fn create_image(cargo_stylus_version: Option<String>, version: &str) -> Result<(
write!(
child.stdin.as_mut().unwrap(),
"\
FROM --platform=linux/amd64 offchainlabs/cargo-stylus-base:{} as base
ARG BUILD_PLATFORM=linux/amd64
FROM --platform=${{BUILD_PLATFORM}} offchainlabs/cargo-stylus-base:{} AS base
RUN rustup toolchain install {}-x86_64-unknown-linux-gnu
RUN rustup default {}-x86_64-unknown-linux-gnu
RUN rustup target add wasm32-unknown-unknown
RUN rustup component add rust-src --toolchain {}-x86_64-unknown-linux-gnu
",
cargo_stylus_version,
version,
version,
version,
toolchain_version,
toolchain_version,
toolchain_version,
)?;
child.wait().map_err(|e| eyre!("wait failed: {e}"))?;
Ok(())
}

fn run_in_docker_container(
cargo_stylus_version: Option<String>,
cargo_stylus_version: &str,
toolchain_version: &str,
command_line: &[&str],
) -> Result<()> {
let cargo_stylus_version =
cargo_stylus_version.unwrap_or_else(|| env!("CARGO_PKG_VERSION").to_string());
let name = format!(
"cargo-stylus-base-{}-toolchain-{}",
cargo_stylus_version, toolchain_version
);
let image_name = image_name(cargo_stylus_version, toolchain_version);
let dir =
std::env::current_dir().map_err(|e| eyre!("failed to find current directory: {e}"))?;
Command::new("docker")
Expand All @@ -96,7 +96,7 @@ fn run_in_docker_container(
.arg("/source")
.arg("-v")
.arg(format!("{}:/source", dir.as_os_str().to_str().unwrap()))
.arg(name)
.arg(image_name)
.args(command_line)
.spawn()
.map_err(|e| eyre!("failed to execute Docker command: {e}"))?
Expand All @@ -116,12 +116,14 @@ pub fn run_reproducible(
"Running reproducible Stylus command with toolchain {}",
toolchain_channel.mint()
);
let cargo_stylus_version =
cargo_stylus_version.unwrap_or_else(|| env!("CARGO_PKG_VERSION").to_string());
let mut command = vec!["cargo", "stylus"];
for s in command_line.iter() {
command.push(s);
}
create_image(cargo_stylus_version.clone(), &toolchain_channel)?;
run_in_docker_container(cargo_stylus_version, &toolchain_channel, &command)
create_image(&cargo_stylus_version, &toolchain_channel)?;
run_in_docker_container(&cargo_stylus_version, &toolchain_channel, &command)
}

fn verify_valid_host() -> Result<()> {
Expand All @@ -146,3 +148,31 @@ fn verify_valid_host() -> Result<()> {
}
Ok(())
}

#[cfg(all(test, feature = "docker-test"))]
mod tests {
use super::*;

#[test]
fn test_create_image_and_check_it_exists() {
let toolchain_version = "1.80.0";
let cargo_stylus_version = "0.5.3";
let image_name = image_name(&cargo_stylus_version, toolchain_version);
println!("image name: {}", image_name);

// Remove existing docker image
Command::new("docker")
.arg("image")
.arg("rm")
.arg("-f")
.arg(&image_name)
.spawn()
.expect("failed to spawn docker image rm")
.wait()
.expect("failed to run docker image rm");

assert!(!image_exists(&image_name).unwrap());
create_image(&cargo_stylus_version, toolchain_version).unwrap();
assert!(image_exists(&image_name).unwrap());
}
}

0 comments on commit f0fe7f2

Please sign in to comment.