|
@@ -1,6 +1,6 @@
|
|
|
use crate::config::{
|
|
|
- AnchorPackage, Config, ConfigOverride, Manifest, ProgramDeployment, ProgramWorkspace, Test,
|
|
|
- WithPath,
|
|
|
+ AnchorPackage, BootstrapMode, BuildConfig, Config, ConfigOverride, Manifest, ProgramDeployment,
|
|
|
+ ProgramWorkspace, Test, WithPath,
|
|
|
};
|
|
|
use anchor_client::Cluster;
|
|
|
use anchor_lang::idl::{IdlAccount, IdlInstruction};
|
|
@@ -79,6 +79,13 @@ pub enum Command {
|
|
|
/// only.
|
|
|
#[clap(short, long)]
|
|
|
solana_version: Option<String>,
|
|
|
+ /// Docker image to use. For --verifiable builds only.
|
|
|
+ #[clap(short, long)]
|
|
|
+ docker_image: Option<String>,
|
|
|
+ /// Bootstrap docker image from scratch, installing all requirements for
|
|
|
+ /// verifiable builds. Only works for debian-based images.
|
|
|
+ #[clap(arg_enum, short, long, default_value = "none")]
|
|
|
+ bootstrap: BootstrapMode,
|
|
|
/// Arguments to pass to the underlying `cargo build-bpf` command
|
|
|
#[clap(
|
|
|
required = false,
|
|
@@ -100,6 +107,13 @@ pub enum Command {
|
|
|
/// only.
|
|
|
#[clap(short, long)]
|
|
|
solana_version: Option<String>,
|
|
|
+ /// Docker image to use. For --verifiable builds only.
|
|
|
+ #[clap(short, long)]
|
|
|
+ docker_image: Option<String>,
|
|
|
+ /// Bootstrap docker image from scratch, installing all requirements for
|
|
|
+ /// verifiable builds. Only works for debian-based images.
|
|
|
+ #[clap(arg_enum, short, long, default_value = "none")]
|
|
|
+ bootstrap: BootstrapMode,
|
|
|
/// Arguments to pass to the underlying `cargo build-bpf` command.
|
|
|
#[clap(
|
|
|
required = false,
|
|
@@ -321,6 +335,8 @@ pub fn entry(opts: Opts) -> Result<()> {
|
|
|
verifiable,
|
|
|
program_name,
|
|
|
solana_version,
|
|
|
+ docker_image,
|
|
|
+ bootstrap,
|
|
|
cargo_args,
|
|
|
} => build(
|
|
|
&opts.cfg_override,
|
|
@@ -329,6 +345,8 @@ pub fn entry(opts: Opts) -> Result<()> {
|
|
|
verifiable,
|
|
|
program_name,
|
|
|
solana_version,
|
|
|
+ docker_image,
|
|
|
+ bootstrap,
|
|
|
None,
|
|
|
None,
|
|
|
cargo_args,
|
|
@@ -337,12 +355,16 @@ pub fn entry(opts: Opts) -> Result<()> {
|
|
|
program_id,
|
|
|
program_name,
|
|
|
solana_version,
|
|
|
+ docker_image,
|
|
|
+ bootstrap,
|
|
|
cargo_args,
|
|
|
} => verify(
|
|
|
&opts.cfg_override,
|
|
|
program_id,
|
|
|
program_name,
|
|
|
solana_version,
|
|
|
+ docker_image,
|
|
|
+ bootstrap,
|
|
|
cargo_args,
|
|
|
),
|
|
|
Command::Deploy { program_name } => deploy(&opts.cfg_override, program_name),
|
|
@@ -543,6 +565,8 @@ pub fn build(
|
|
|
verifiable: bool,
|
|
|
program_name: Option<String>,
|
|
|
solana_version: Option<String>,
|
|
|
+ docker_image: Option<String>,
|
|
|
+ bootstrap: BootstrapMode,
|
|
|
stdout: Option<File>, // Used for the package registry server.
|
|
|
stderr: Option<File>, // Used for the package registry server.
|
|
|
cargo_args: Vec<String>,
|
|
@@ -553,6 +577,12 @@ pub fn build(
|
|
|
}
|
|
|
|
|
|
let cfg = Config::discover(cfg_override)?.expect("Not in workspace.");
|
|
|
+ let build_config = BuildConfig {
|
|
|
+ verifiable,
|
|
|
+ solana_version: solana_version.or_else(|| cfg.solana_version.clone()),
|
|
|
+ docker_image: docker_image.unwrap_or_else(|| cfg.docker()),
|
|
|
+ bootstrap,
|
|
|
+ };
|
|
|
let cfg_parent = cfg.path().parent().expect("Invalid Anchor.toml");
|
|
|
|
|
|
let cargo = Manifest::discover()?;
|
|
@@ -573,11 +603,6 @@ pub fn build(
|
|
|
fs::create_dir_all(cfg_parent.join(&cfg.workspace.types))?;
|
|
|
};
|
|
|
|
|
|
- let solana_version = match solana_version.is_some() {
|
|
|
- true => solana_version,
|
|
|
- false => cfg.solana_version.clone(),
|
|
|
- };
|
|
|
-
|
|
|
match cargo {
|
|
|
// No Cargo.toml so build the entire workspace.
|
|
|
None => build_all(
|
|
@@ -585,8 +610,7 @@ pub fn build(
|
|
|
cfg.path(),
|
|
|
idl_out,
|
|
|
idl_ts_out,
|
|
|
- verifiable,
|
|
|
- solana_version,
|
|
|
+ &build_config,
|
|
|
stdout,
|
|
|
stderr,
|
|
|
cargo_args,
|
|
@@ -597,8 +621,7 @@ pub fn build(
|
|
|
cfg.path(),
|
|
|
idl_out,
|
|
|
idl_ts_out,
|
|
|
- verifiable,
|
|
|
- solana_version,
|
|
|
+ &build_config,
|
|
|
stdout,
|
|
|
stderr,
|
|
|
cargo_args,
|
|
@@ -609,8 +632,7 @@ pub fn build(
|
|
|
cargo.path().to_path_buf(),
|
|
|
idl_out,
|
|
|
idl_ts_out,
|
|
|
- verifiable,
|
|
|
- solana_version,
|
|
|
+ &build_config,
|
|
|
stdout,
|
|
|
stderr,
|
|
|
cargo_args,
|
|
@@ -628,8 +650,7 @@ fn build_all(
|
|
|
cfg_path: &Path,
|
|
|
idl_out: Option<PathBuf>,
|
|
|
idl_ts_out: Option<PathBuf>,
|
|
|
- verifiable: bool,
|
|
|
- solana_version: Option<String>,
|
|
|
+ build_config: &BuildConfig,
|
|
|
stdout: Option<File>, // Used for the package registry server.
|
|
|
stderr: Option<File>, // Used for the package registry server.
|
|
|
cargo_args: Vec<String>,
|
|
@@ -644,8 +665,7 @@ fn build_all(
|
|
|
p.join("Cargo.toml"),
|
|
|
idl_out.clone(),
|
|
|
idl_ts_out.clone(),
|
|
|
- verifiable,
|
|
|
- solana_version.clone(),
|
|
|
+ build_config,
|
|
|
stdout.as_ref().map(|f| f.try_clone()).transpose()?,
|
|
|
stderr.as_ref().map(|f| f.try_clone()).transpose()?,
|
|
|
cargo_args.clone(),
|
|
@@ -665,8 +685,7 @@ fn build_cwd(
|
|
|
cargo_toml: PathBuf,
|
|
|
idl_out: Option<PathBuf>,
|
|
|
idl_ts_out: Option<PathBuf>,
|
|
|
- verifiable: bool,
|
|
|
- solana_version: Option<String>,
|
|
|
+ build_config: &BuildConfig,
|
|
|
stdout: Option<File>,
|
|
|
stderr: Option<File>,
|
|
|
cargo_args: Vec<String>,
|
|
@@ -675,9 +694,9 @@ fn build_cwd(
|
|
|
None => return Err(anyhow!("Unable to find parent")),
|
|
|
Some(p) => std::env::set_current_dir(&p)?,
|
|
|
};
|
|
|
- match verifiable {
|
|
|
+ match build_config.verifiable {
|
|
|
false => _build_cwd(cfg, idl_out, idl_ts_out, cargo_args),
|
|
|
- true => build_cwd_verifiable(cfg, cargo_toml, solana_version, stdout, stderr, cargo_args),
|
|
|
+ true => build_cwd_verifiable(cfg, cargo_toml, build_config, stdout, stderr, cargo_args),
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -686,7 +705,7 @@ fn build_cwd(
|
|
|
fn build_cwd_verifiable(
|
|
|
cfg: &WithPath<Config>,
|
|
|
cargo_toml: PathBuf,
|
|
|
- solana_version: Option<String>,
|
|
|
+ build_config: &BuildConfig,
|
|
|
stdout: Option<File>,
|
|
|
stderr: Option<File>,
|
|
|
cargo_args: Vec<String>,
|
|
@@ -707,68 +726,44 @@ fn build_cwd_verifiable(
|
|
|
cfg,
|
|
|
container_name,
|
|
|
cargo_toml,
|
|
|
- solana_version,
|
|
|
+ build_config,
|
|
|
stdout,
|
|
|
stderr,
|
|
|
cargo_args,
|
|
|
);
|
|
|
|
|
|
- // Wipe the generated docker-target dir.
|
|
|
- println!("Cleaning up the docker target directory");
|
|
|
- let exit = std::process::Command::new("docker")
|
|
|
- .args(&[
|
|
|
- "exec",
|
|
|
- container_name,
|
|
|
- "rm",
|
|
|
- "-rf",
|
|
|
- "/workdir/docker-target",
|
|
|
- ])
|
|
|
- .stdout(Stdio::inherit())
|
|
|
- .stderr(Stdio::inherit())
|
|
|
- .output()
|
|
|
- .map_err(|e| anyhow::format_err!("Docker rm docker-target failed: {}", e.to_string()))?;
|
|
|
- if !exit.status.success() {
|
|
|
- return Err(anyhow!("Failed to build program"));
|
|
|
- }
|
|
|
-
|
|
|
- // Remove the docker image.
|
|
|
- println!("Removing the docker image");
|
|
|
- let exit = std::process::Command::new("docker")
|
|
|
- .args(&["rm", "-f", container_name])
|
|
|
- .stdout(Stdio::inherit())
|
|
|
- .stderr(Stdio::inherit())
|
|
|
- .output()
|
|
|
- .map_err(|e| anyhow::format_err!("{}", e.to_string()))?;
|
|
|
- if !exit.status.success() {
|
|
|
- println!("Unable to remove docker container");
|
|
|
- std::process::exit(exit.status.code().unwrap_or(1));
|
|
|
- }
|
|
|
-
|
|
|
- // Build the idl.
|
|
|
- println!("Extracting the IDL");
|
|
|
- if let Ok(Some(idl)) = extract_idl("src/lib.rs") {
|
|
|
- // Write out the JSON file.
|
|
|
- println!("Writing the IDL file");
|
|
|
- let out_file = workspace_dir.join(format!("target/idl/{}.json", idl.name));
|
|
|
- write_idl(&idl, OutFile::File(out_file))?;
|
|
|
-
|
|
|
- // Write out the TypeScript type.
|
|
|
- println!("Writing the .ts file");
|
|
|
- let ts_file = workspace_dir.join(format!("target/types/{}.ts", idl.name));
|
|
|
- fs::write(&ts_file, template::idl_ts(&idl)?)?;
|
|
|
-
|
|
|
- // Copy out the TypeScript type.
|
|
|
- if !&cfg.workspace.types.is_empty() {
|
|
|
- fs::copy(
|
|
|
- ts_file,
|
|
|
- workspace_dir
|
|
|
- .join(&cfg.workspace.types)
|
|
|
- .join(idl.name)
|
|
|
- .with_extension("ts"),
|
|
|
- )?;
|
|
|
+ match &result {
|
|
|
+ Err(e) => {
|
|
|
+ eprintln!("Error during Docker build: {:?}", e);
|
|
|
+ }
|
|
|
+ Ok(_) => {
|
|
|
+ // Build the idl.
|
|
|
+ println!("Extracting the IDL");
|
|
|
+ if let Ok(Some(idl)) = extract_idl("src/lib.rs") {
|
|
|
+ // Write out the JSON file.
|
|
|
+ println!("Writing the IDL file");
|
|
|
+ let out_file = workspace_dir.join(format!("target/idl/{}.json", idl.name));
|
|
|
+ write_idl(&idl, OutFile::File(out_file))?;
|
|
|
+
|
|
|
+ // Write out the TypeScript type.
|
|
|
+ println!("Writing the .ts file");
|
|
|
+ let ts_file = workspace_dir.join(format!("target/types/{}.ts", idl.name));
|
|
|
+ fs::write(&ts_file, template::idl_ts(&idl)?)?;
|
|
|
+
|
|
|
+ // Copy out the TypeScript type.
|
|
|
+ if !&cfg.workspace.types.is_empty() {
|
|
|
+ fs::copy(
|
|
|
+ ts_file,
|
|
|
+ workspace_dir
|
|
|
+ .join(&cfg.workspace.types)
|
|
|
+ .join(idl.name)
|
|
|
+ .with_extension("ts"),
|
|
|
+ )?;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ println!("Build success");
|
|
|
}
|
|
|
}
|
|
|
- println!("Build success");
|
|
|
|
|
|
result
|
|
|
}
|
|
@@ -777,7 +772,7 @@ fn docker_build(
|
|
|
cfg: &WithPath<Config>,
|
|
|
container_name: &str,
|
|
|
cargo_toml: PathBuf,
|
|
|
- solana_version: Option<String>,
|
|
|
+ build_config: &BuildConfig,
|
|
|
stdout: Option<File>,
|
|
|
stderr: Option<File>,
|
|
|
cargo_args: Vec<String>,
|
|
@@ -785,14 +780,16 @@ fn docker_build(
|
|
|
let binary_name = Manifest::from_path(&cargo_toml)?.lib_name()?;
|
|
|
|
|
|
// Docker vars.
|
|
|
- let image_name = cfg.docker();
|
|
|
+ let workdir = Path::new("/workdir");
|
|
|
let volume_mount = format!(
|
|
|
- "{}:/workdir",
|
|
|
- cfg.path().parent().unwrap().canonicalize()?.display()
|
|
|
+ "{}:{}",
|
|
|
+ cfg.path().parent().unwrap().canonicalize()?.display(),
|
|
|
+ workdir.to_str().unwrap(),
|
|
|
);
|
|
|
- println!("Using image {:?}", image_name);
|
|
|
+ println!("Using image {:?}", build_config.docker_image);
|
|
|
|
|
|
// Start the docker image running detached in the background.
|
|
|
+ let target_dir = workdir.join("docker-target");
|
|
|
println!("Run docker image");
|
|
|
let exit = std::process::Command::new("docker")
|
|
|
.args(&[
|
|
@@ -802,10 +799,15 @@ fn docker_build(
|
|
|
"--name",
|
|
|
container_name,
|
|
|
"--env",
|
|
|
- "CARGO_TARGET_DIR=/workdir/docker-target",
|
|
|
+ &format!(
|
|
|
+ "CARGO_TARGET_DIR={}",
|
|
|
+ target_dir.as_path().to_str().unwrap()
|
|
|
+ ),
|
|
|
"-v",
|
|
|
&volume_mount,
|
|
|
- &image_name,
|
|
|
+ "-w",
|
|
|
+ workdir.to_str().unwrap(),
|
|
|
+ &build_config.docker_image,
|
|
|
"bash",
|
|
|
])
|
|
|
.stdout(Stdio::inherit())
|
|
@@ -816,58 +818,84 @@ fn docker_build(
|
|
|
return Err(anyhow!("Failed to build program"));
|
|
|
}
|
|
|
|
|
|
+ let result = docker_prep(container_name, build_config).and_then(|_| {
|
|
|
+ let cfg_parent = cfg.path().parent().unwrap();
|
|
|
+ docker_build_bpf(
|
|
|
+ container_name,
|
|
|
+ cargo_toml.as_path(),
|
|
|
+ cfg_parent,
|
|
|
+ target_dir.as_path(),
|
|
|
+ binary_name,
|
|
|
+ stdout,
|
|
|
+ stderr,
|
|
|
+ cargo_args,
|
|
|
+ )
|
|
|
+ });
|
|
|
+
|
|
|
+ // Cleanup regardless of errors
|
|
|
+ docker_cleanup(container_name, target_dir.as_path())?;
|
|
|
+
|
|
|
+ // Done.
|
|
|
+ result
|
|
|
+}
|
|
|
+
|
|
|
+fn docker_prep(container_name: &str, build_config: &BuildConfig) -> Result<()> {
|
|
|
// Set the solana version in the container, if given. Otherwise use the
|
|
|
// default.
|
|
|
- if let Some(solana_version) = solana_version {
|
|
|
- println!("Using solana version: {}", solana_version);
|
|
|
+ match build_config.bootstrap {
|
|
|
+ BootstrapMode::Debian => {
|
|
|
+ // Install build requirements
|
|
|
+ docker_exec(container_name, &["apt", "update"])?;
|
|
|
+ docker_exec(
|
|
|
+ container_name,
|
|
|
+ &["apt", "install", "-y", "curl", "build-essential"],
|
|
|
+ )?;
|
|
|
|
|
|
- // Fetch the installer.
|
|
|
- let exit = std::process::Command::new("docker")
|
|
|
- .args(&[
|
|
|
- "exec",
|
|
|
+ // Install Rust
|
|
|
+ docker_exec(
|
|
|
container_name,
|
|
|
+ &["curl", "https://sh.rustup.rs", "-sfo", "rustup.sh"],
|
|
|
+ )?;
|
|
|
+ docker_exec(container_name, &["sh", "rustup.sh", "-y"])?;
|
|
|
+ docker_exec(container_name, &["rm", "-f", "rustup.sh"])?;
|
|
|
+ }
|
|
|
+ BootstrapMode::None => {}
|
|
|
+ }
|
|
|
+
|
|
|
+ if let Some(solana_version) = &build_config.solana_version {
|
|
|
+ println!("Using solana version: {}", solana_version);
|
|
|
+
|
|
|
+ // Install Solana CLI
|
|
|
+ docker_exec(
|
|
|
+ container_name,
|
|
|
+ &[
|
|
|
"curl",
|
|
|
"-sSfL",
|
|
|
&format!("https://release.solana.com/v{0}/install", solana_version,),
|
|
|
"-o",
|
|
|
"solana_installer.sh",
|
|
|
- ])
|
|
|
- .stdout(Stdio::inherit())
|
|
|
- .stderr(Stdio::inherit())
|
|
|
- .output()
|
|
|
- .map_err(|e| anyhow!("Failed to set solana version: {:?}", e))?;
|
|
|
- if !exit.status.success() {
|
|
|
- return Err(anyhow!("Failed to set solana version"));
|
|
|
- }
|
|
|
-
|
|
|
- // Run the installer.
|
|
|
- let exit = std::process::Command::new("docker")
|
|
|
- .args(&["exec", container_name, "sh", "solana_installer.sh"])
|
|
|
- .stdout(Stdio::inherit())
|
|
|
- .stderr(Stdio::inherit())
|
|
|
- .output()
|
|
|
- .map_err(|e| anyhow!("Failed to set solana version: {:?}", e))?;
|
|
|
- if !exit.status.success() {
|
|
|
- return Err(anyhow!("Failed to set solana version"));
|
|
|
- }
|
|
|
-
|
|
|
- // Remove the installer.
|
|
|
- let exit = std::process::Command::new("docker")
|
|
|
- .args(&["exec", container_name, "rm", "-f", "solana_installer.sh"])
|
|
|
- .stdout(Stdio::inherit())
|
|
|
- .stderr(Stdio::inherit())
|
|
|
- .output()
|
|
|
- .map_err(|e| anyhow!("Failed to remove installer: {:?}", e))?;
|
|
|
- if !exit.status.success() {
|
|
|
- return Err(anyhow!("Failed to remove installer"));
|
|
|
- }
|
|
|
+ ],
|
|
|
+ )?;
|
|
|
+ docker_exec(container_name, &["sh", "solana_installer.sh"])?;
|
|
|
+ docker_exec(container_name, &["rm", "-f", "solana_installer.sh"])?;
|
|
|
}
|
|
|
+ Ok(())
|
|
|
+}
|
|
|
|
|
|
- let manifest_path = pathdiff::diff_paths(
|
|
|
- cargo_toml.canonicalize()?,
|
|
|
- cfg.path().parent().unwrap().canonicalize()?,
|
|
|
- )
|
|
|
- .ok_or_else(|| anyhow!("Unable to diff paths"))?;
|
|
|
+#[allow(clippy::too_many_arguments)]
|
|
|
+fn docker_build_bpf(
|
|
|
+ container_name: &str,
|
|
|
+ cargo_toml: &Path,
|
|
|
+ cfg_parent: &Path,
|
|
|
+ target_dir: &Path,
|
|
|
+ binary_name: String,
|
|
|
+ stdout: Option<File>,
|
|
|
+ stderr: Option<File>,
|
|
|
+ cargo_args: Vec<String>,
|
|
|
+) -> Result<()> {
|
|
|
+ let manifest_path =
|
|
|
+ pathdiff::diff_paths(cargo_toml.canonicalize()?, cfg_parent.canonicalize()?)
|
|
|
+ .ok_or_else(|| anyhow!("Unable to diff paths"))?;
|
|
|
println!(
|
|
|
"Building {} manifest: {:?}",
|
|
|
binary_name,
|
|
@@ -878,6 +906,8 @@ fn docker_build(
|
|
|
let exit = std::process::Command::new("docker")
|
|
|
.args(&[
|
|
|
"exec",
|
|
|
+ "--env",
|
|
|
+ "PATH=/root/.local/share/solana/install/active_release/bin:/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
|
|
container_name,
|
|
|
"cargo",
|
|
|
"build-bpf",
|
|
@@ -901,10 +931,7 @@ fn docker_build(
|
|
|
|
|
|
// Copy the binary out of the docker image.
|
|
|
println!("Copying out the build artifacts");
|
|
|
- let out_file = cfg
|
|
|
- .path()
|
|
|
- .parent()
|
|
|
- .unwrap()
|
|
|
+ let out_file = cfg_parent
|
|
|
.canonicalize()?
|
|
|
.join(format!("target/verifiable/{}.so", binary_name))
|
|
|
.display()
|
|
@@ -912,9 +939,12 @@ fn docker_build(
|
|
|
|
|
|
// This requires the target directory of any built program to be located at
|
|
|
// the root of the workspace.
|
|
|
+ let mut bin_path = target_dir.join("deploy");
|
|
|
+ bin_path.push(format!("{}.so", binary_name));
|
|
|
let bin_artifact = format!(
|
|
|
- "{}:/workdir/docker-target/deploy/{}.so",
|
|
|
- container_name, binary_name
|
|
|
+ "{}:{}",
|
|
|
+ container_name,
|
|
|
+ bin_path.as_path().to_str().unwrap()
|
|
|
);
|
|
|
let exit = std::process::Command::new("docker")
|
|
|
.args(&["cp", &bin_artifact, &out_file])
|
|
@@ -923,15 +953,48 @@ fn docker_build(
|
|
|
.output()
|
|
|
.map_err(|e| anyhow::format_err!("{}", e.to_string()))?;
|
|
|
if !exit.status.success() {
|
|
|
- return Err(anyhow!(
|
|
|
+ Err(anyhow!(
|
|
|
"Failed to copy binary out of docker. Is the target directory set correctly?"
|
|
|
- ));
|
|
|
+ ))
|
|
|
+ } else {
|
|
|
+ Ok(())
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- // Done.
|
|
|
+fn docker_cleanup(container_name: &str, target_dir: &Path) -> Result<()> {
|
|
|
+ // Wipe the generated docker-target dir.
|
|
|
+ println!("Cleaning up the docker target directory");
|
|
|
+ docker_exec(container_name, &["rm", "-rf", target_dir.to_str().unwrap()])?;
|
|
|
+
|
|
|
+ // Remove the docker image.
|
|
|
+ println!("Removing the docker image");
|
|
|
+ let exit = std::process::Command::new("docker")
|
|
|
+ .args(&["rm", "-f", container_name])
|
|
|
+ .stdout(Stdio::inherit())
|
|
|
+ .stderr(Stdio::inherit())
|
|
|
+ .output()
|
|
|
+ .map_err(|e| anyhow::format_err!("{}", e.to_string()))?;
|
|
|
+ if !exit.status.success() {
|
|
|
+ println!("Unable to remove docker container");
|
|
|
+ std::process::exit(exit.status.code().unwrap_or(1));
|
|
|
+ }
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
+fn docker_exec(container_name: &str, args: &[&str]) -> Result<()> {
|
|
|
+ let exit = std::process::Command::new("docker")
|
|
|
+ .args([&["exec", container_name], args].concat())
|
|
|
+ .stdout(Stdio::inherit())
|
|
|
+ .stderr(Stdio::inherit())
|
|
|
+ .output()
|
|
|
+ .map_err(|e| anyhow!("Failed to run command \"{:?}\": {:?}", args, e))?;
|
|
|
+ if !exit.status.success() {
|
|
|
+ Err(anyhow!("Failed to run command: {:?}", args))
|
|
|
+ } else {
|
|
|
+ Ok(())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
fn _build_cwd(
|
|
|
cfg: &WithPath<Config>,
|
|
|
idl_out: Option<PathBuf>,
|
|
@@ -987,6 +1050,8 @@ fn verify(
|
|
|
program_id: Pubkey,
|
|
|
program_name: Option<String>,
|
|
|
solana_version: Option<String>,
|
|
|
+ docker_image: Option<String>,
|
|
|
+ bootstrap: BootstrapMode,
|
|
|
cargo_args: Vec<String>,
|
|
|
) -> Result<()> {
|
|
|
// Change to the workspace member directory, if needed.
|
|
@@ -1002,16 +1067,15 @@ fn verify(
|
|
|
let cur_dir = std::env::current_dir()?;
|
|
|
build(
|
|
|
cfg_override,
|
|
|
- None,
|
|
|
- None,
|
|
|
- true,
|
|
|
- None,
|
|
|
- match solana_version.is_some() {
|
|
|
- true => solana_version,
|
|
|
- false => cfg.solana_version.clone(),
|
|
|
- },
|
|
|
- None,
|
|
|
- None,
|
|
|
+ None, // idl
|
|
|
+ None, // idl ts
|
|
|
+ true, // verifiable
|
|
|
+ None, // program name
|
|
|
+ solana_version.or_else(|| cfg.solana_version.clone()), // solana version
|
|
|
+ docker_image, // docker image
|
|
|
+ bootstrap, // bootstrap docker image
|
|
|
+ None, // stdout
|
|
|
+ None, // stderr
|
|
|
cargo_args,
|
|
|
)?;
|
|
|
std::env::set_current_dir(&cur_dir)?;
|
|
@@ -1526,6 +1590,8 @@ fn test(
|
|
|
None,
|
|
|
None,
|
|
|
None,
|
|
|
+ BootstrapMode::None,
|
|
|
+ None,
|
|
|
None,
|
|
|
cargo_args,
|
|
|
)?;
|
|
@@ -2432,7 +2498,9 @@ fn publish(
|
|
|
None,
|
|
|
true,
|
|
|
Some(program_name),
|
|
|
- cfg.solana_version.clone(),
|
|
|
+ None,
|
|
|
+ None,
|
|
|
+ BootstrapMode::None,
|
|
|
None,
|
|
|
None,
|
|
|
cargo_args,
|
|
@@ -2529,6 +2597,8 @@ fn localnet(
|
|
|
None,
|
|
|
None,
|
|
|
None,
|
|
|
+ BootstrapMode::None,
|
|
|
+ None,
|
|
|
None,
|
|
|
cargo_args,
|
|
|
)?;
|