fix: use --platform opt when pulling containers (#435)
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
@@ -18,15 +19,42 @@ use crate::{execution_context::ExecutionContext, utils::require};
|
|||||||
// themselves or when using docker-compose.
|
// themselves or when using docker-compose.
|
||||||
const NONEXISTENT_REPO: &str = "repository does not exist";
|
const NONEXISTENT_REPO: &str = "repository does not exist";
|
||||||
|
|
||||||
|
/// Uniquely identifies a `Container`.
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Container {
|
||||||
|
/// `Repository` and `Tag`
|
||||||
|
///
|
||||||
|
/// format: `Repository:Tag`, e.g., `fedora:latest`.
|
||||||
|
repo_tag: String,
|
||||||
|
/// Platform
|
||||||
|
///
|
||||||
|
/// format: `OS/Architecture`, e.g., `linux/amd64`.
|
||||||
|
platform: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Container {
|
||||||
|
/// Construct a new `Container`.
|
||||||
|
fn new(repo_tag: String, platform: String) -> Self {
|
||||||
|
Self { repo_tag, platform }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Container {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
// e.g., "`fedora/latest` for `linux/amd64`"
|
||||||
|
write!(f, "`{}` for `{}`", self.repo_tag, self.platform)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a Vector of all containers, with Strings in the format
|
/// Returns a Vector of all containers, with Strings in the format
|
||||||
/// "REGISTRY/[PATH/]CONTAINER_NAME:TAG"
|
/// "REGISTRY/[PATH/]CONTAINER_NAME:TAG"
|
||||||
fn list_containers(crt: &Path) -> Result<Vec<String>> {
|
fn list_containers(crt: &Path) -> Result<Vec<Container>> {
|
||||||
debug!(
|
debug!(
|
||||||
"Querying '{} image ls --format \"{{{{.Repository}}}}:{{{{.Tag}}}}\"' for containers",
|
"Querying '{} image ls --format \"{{{{.Repository}}}}:{{{{.Tag}}}}/{{{{.ID}}}}\"' for containers",
|
||||||
crt.display()
|
crt.display()
|
||||||
);
|
);
|
||||||
let output = Command::new(crt)
|
let output = Command::new(crt)
|
||||||
.args(["image", "ls", "--format", "{{.Repository}}:{{.Tag}}"])
|
.args(["image", "ls", "--format", "{{.Repository}}:{{.Tag}}/{{.ID}}"])
|
||||||
.output_checked_with_utf8(|_| Ok(()))?;
|
.output_checked_with_utf8(|_| Ok(()))?;
|
||||||
|
|
||||||
let mut retval = vec![];
|
let mut retval = vec![];
|
||||||
@@ -49,7 +77,26 @@ fn list_containers(crt: &Path) -> Result<Vec<String>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug!("Using container '{}'", line);
|
debug!("Using container '{}'", line);
|
||||||
retval.push(String::from(line));
|
|
||||||
|
// line is of format: `Repository:Tag/ImageID`, e.g., `fedora:latest/be300d2b6d94`.
|
||||||
|
let split_res = line.split('/').collect::<Vec<&str>>();
|
||||||
|
assert_eq!(split_res.len(), 2);
|
||||||
|
let (repo_tag, image_id) = (split_res[0], split_res[1]);
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"Querying '{} image inspect --format \"{{{{.Os}}}}/{{{{.Architecture}}}}\"' for container {}",
|
||||||
|
crt.display(),
|
||||||
|
image_id
|
||||||
|
);
|
||||||
|
let inspect_output = Command::new(crt)
|
||||||
|
.args(["image", "inspect", image_id, "--format", "{{.Os}}/{{.Architecture}}"])
|
||||||
|
.output_checked_with_utf8(|_| Ok(()))?;
|
||||||
|
let mut platform = inspect_output.stdout;
|
||||||
|
// truncate the tailing new line character
|
||||||
|
platform.truncate(platform.len() - 1);
|
||||||
|
assert!(platform.contains('/'));
|
||||||
|
|
||||||
|
retval.push(Container::new(repo_tag.to_string(), platform));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(retval)
|
Ok(retval)
|
||||||
@@ -67,7 +114,12 @@ pub fn run_containers(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
for container in containers.iter() {
|
for container in containers.iter() {
|
||||||
debug!("Pulling container '{}'", container);
|
debug!("Pulling container '{}'", container);
|
||||||
let args = vec!["pull", &container[..]];
|
let args = vec![
|
||||||
|
"pull",
|
||||||
|
container.repo_tag.as_str(),
|
||||||
|
"--platform",
|
||||||
|
container.platform.as_str(),
|
||||||
|
];
|
||||||
let mut exec = ctx.run_type().execute(&crt);
|
let mut exec = ctx.run_type().execute(&crt);
|
||||||
|
|
||||||
if let Err(e) = exec.args(&args).status_checked() {
|
if let Err(e) = exec.args(&args).status_checked() {
|
||||||
|
|||||||
Reference in New Issue
Block a user