Skip to content

Commit 6a08d43

Browse files
committed
Simplify working with Docker containers and volumes.
Renamed `DataVolume` to `ContainerDataVolume`, `Container` to `ChildContainer`, and `DeleteContainer` to `ChildContainerInfo`. Created `DockerVolume` and `DockerContainer` to handle the logic of starting, stopping, creating, etc. docker volumes and containers for simple cases.
1 parent eca0950 commit 6a08d43

File tree

5 files changed

+238
-227
lines changed

5 files changed

+238
-227
lines changed

src/bin/commands/containers.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -397,34 +397,34 @@ pub fn create_persistent_volume(
397397
};
398398
let mount_finder = docker::MountFinder::create(engine)?;
399399
let dirs = docker::ToolchainDirectories::assemble(&mount_finder, toolchain.clone())?;
400-
let container = dirs.unique_container_identifier(&toolchain.host().target)?;
401-
let volume = dirs.unique_toolchain_identifier()?;
400+
let container_id = dirs.unique_container_identifier(&toolchain.host().target)?;
401+
let volume_id = dirs.unique_toolchain_identifier()?;
402+
let volume = docker::DockerVolume::new(engine, &volume_id);
402403

403-
if docker::volume_exists(engine, &volume, msg_info)? {
404-
eyre::bail!("Error: volume {volume} already exists.");
404+
if volume.exists(msg_info)? {
405+
eyre::bail!("Error: volume {volume_id} already exists.");
405406
}
406407

407-
docker::subcommand(engine, "volume")
408-
.args(["create", &volume])
409-
.run_and_get_status(msg_info, false)?;
408+
volume.create(msg_info)?;
410409

411410
// stop the container if it's already running
412-
let state = docker::container_state(engine, &container, msg_info)?;
411+
let container = docker::DockerContainer::new(engine, &container_id);
412+
let state = container.state(msg_info)?;
413413
if !state.is_stopped() {
414-
msg_info.warn(format_args!("container {container} was running."))?;
415-
docker::container_stop_default(engine, &container, msg_info)?;
414+
msg_info.warn(format_args!("container {container_id} was running."))?;
415+
container.stop_default(msg_info)?;
416416
}
417417
if state.exists() {
418-
msg_info.warn(format_args!("container {container} was exited."))?;
419-
docker::container_rm(engine, &container, msg_info)?;
418+
msg_info.warn(format_args!("container {container_id} was exited."))?;
419+
container.remove(msg_info)?;
420420
}
421421

422422
// create a dummy running container to copy data over
423423
let mount_prefix = docker::MOUNT_PREFIX;
424424
let mut docker = docker::subcommand(engine, "run");
425-
docker.args(["--name", &container]);
425+
docker.args(["--name", &container_id]);
426426
docker.arg("--rm");
427-
docker.args(["-v", &format!("{}:{}", volume, mount_prefix)]);
427+
docker.args(["-v", &format!("{}:{}", volume_id, mount_prefix)]);
428428
docker.arg("-d");
429429
let is_tty = io::Stdin::is_atty() && io::Stdout::is_atty() && io::Stderr::is_atty();
430430
if is_tty {
@@ -440,15 +440,15 @@ pub fn create_persistent_volume(
440440
docker.args(["sh", "-c", "sleep infinity"]);
441441
}
442442
// store first, since failing to non-existing container is fine
443-
docker::Container::create(engine.clone(), container.clone())?;
443+
docker::ChildContainer::create(engine.clone(), container_id.clone())?;
444444
docker.run_and_get_status(msg_info, false)?;
445445

446-
let data_volume = docker::remote::DataVolume::new(engine, &container, &dirs);
446+
let data_volume = docker::ContainerDataVolume::new(engine, &container_id, &dirs);
447447
data_volume.copy_xargo(mount_prefix.as_ref(), msg_info)?;
448448
data_volume.copy_cargo(mount_prefix.as_ref(), copy_registry, msg_info)?;
449449
data_volume.copy_rust(None, mount_prefix.as_ref(), msg_info)?;
450450

451-
docker::Container::finish_static(is_tty, msg_info);
451+
docker::ChildContainer::finish_static(is_tty, msg_info);
452452

453453
Ok(())
454454
}
@@ -465,13 +465,14 @@ pub fn remove_persistent_volume(
465465
};
466466
let mount_finder = docker::MountFinder::create(engine)?;
467467
let dirs = docker::ToolchainDirectories::assemble(&mount_finder, toolchain)?;
468-
let volume = dirs.unique_toolchain_identifier()?;
468+
let volume_id = dirs.unique_toolchain_identifier()?;
469+
let volume = docker::DockerVolume::new(engine, &volume_id);
469470

470-
if !docker::volume_exists(engine, &volume, msg_info)? {
471-
eyre::bail!("Error: volume {volume} does not exist.");
471+
if !volume.exists(msg_info)? {
472+
eyre::bail!("Error: volume {volume_id} does not exist.");
472473
}
473474

474-
docker::volume_rm(engine, &volume, msg_info)?;
475+
volume.remove(msg_info)?;
475476

476477
Ok(())
477478
}

src/docker/local.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ pub(crate) fn run(
5151
msg_info,
5252
)?;
5353

54-
let container = toolchain_dirs.unique_container_identifier(options.target.target())?;
55-
docker.args(["--name", &container]);
54+
let container_id = toolchain_dirs.unique_container_identifier(options.target.target())?;
55+
docker.args(["--name", &container_id]);
5656
docker.arg("--rm");
5757

5858
docker_seccomp(&mut docker, engine.kind, &options.target, &paths.metadata)
@@ -124,7 +124,7 @@ pub(crate) fn run(
124124
.wrap_err("when building custom image")?;
125125
}
126126

127-
Container::create(engine.clone(), container)?;
127+
ChildContainer::create(engine.clone(), container_id)?;
128128
let status = docker
129129
.arg(&image_name)
130130
.args(["sh", "-c", &build_command(toolchain_dirs, &cmd)])
@@ -138,7 +138,7 @@ pub(crate) fn run(
138138
// SAFETY: an atomic load.
139139
let is_terminated = unsafe { crate::errors::TERMINATED.load(Ordering::SeqCst) };
140140
if !is_terminated {
141-
Container::exit_static();
141+
ChildContainer::exit_static();
142142
}
143143

144144
status

src/docker/remote.rs

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,13 @@ use crate::shell::{MessageInfo, Stream};
1717
use crate::temp;
1818
use crate::TargetTriple;
1919

20-
#[derive(Debug, Clone)]
21-
enum VolumeId {
22-
Keep(String),
23-
Discard,
24-
}
25-
2620
// prevent further commands from running if we handled
2721
// a signal earlier, and the volume is exited.
2822
// this isn't required, but avoids unnecessary
2923
// commands while the container is cleaning up.
3024
macro_rules! bail_container_exited {
3125
() => {{
32-
if !Container::exists_static() {
26+
if !ChildContainer::exists_static() {
3327
eyre::bail!("container already exited due to signal");
3428
}
3529
}};
@@ -40,26 +34,7 @@ fn subcommand_or_exit(engine: &Engine, cmd: &str) -> Result<Command> {
4034
Ok(subcommand(engine, cmd))
4135
}
4236

43-
#[derive(Debug)]
44-
pub struct DataVolume<'a, 'b, 'c> {
45-
engine: &'a Engine,
46-
container: &'b str,
47-
toolchain_dirs: &'c ToolchainDirectories,
48-
}
49-
50-
impl<'a, 'b, 'c> DataVolume<'a, 'b, 'c> {
51-
pub const fn new(
52-
engine: &'a Engine,
53-
container: &'b str,
54-
toolchain_dirs: &'c ToolchainDirectories,
55-
) -> Self {
56-
Self {
57-
engine,
58-
container,
59-
toolchain_dirs,
60-
}
61-
}
62-
37+
impl<'a, 'b, 'c> ContainerDataVolume<'a, 'b, 'c> {
6338
fn create_dir(&self, dir: &Path, msg_info: &mut MessageInfo) -> Result<ExitStatus> {
6439
// make our parent directory if needed
6540
subcommand_or_exit(self.engine, "exec")?
@@ -636,9 +611,9 @@ pub(crate) fn run(
636611
// note that since we use `docker run --rm`, it's very
637612
// unlikely the container state existed before.
638613
let toolchain_id = toolchain_dirs.unique_toolchain_identifier()?;
639-
let container = toolchain_dirs.unique_container_identifier(target.target())?;
614+
let container_id = toolchain_dirs.unique_container_identifier(target.target())?;
640615
let volume = {
641-
let existing = existing_volumes(engine, toolchain_dirs.toolchain(), msg_info)?;
616+
let existing = DockerVolume::existing(engine, toolchain_dirs.toolchain(), msg_info)?;
642617
if existing.iter().any(|v| v == &toolchain_id) {
643618
VolumeId::Keep(toolchain_id)
644619
} else {
@@ -652,14 +627,16 @@ pub(crate) fn run(
652627
VolumeId::Discard
653628
}
654629
};
655-
let state = container_state(engine, &container, msg_info)?;
630+
631+
let container = DockerContainer::new(engine, &container_id);
632+
let state = container.state(msg_info)?;
656633
if !state.is_stopped() {
657-
msg_info.warn(format_args!("container {container} was running."))?;
658-
container_stop_default(engine, &container, msg_info)?;
634+
msg_info.warn(format_args!("container {container_id} was running."))?;
635+
container.stop_default(msg_info)?;
659636
}
660637
if state.exists() {
661-
msg_info.warn(format_args!("container {container} was exited."))?;
662-
container_rm(engine, &container, msg_info)?;
638+
msg_info.warn(format_args!("container {container_id} was exited."))?;
639+
container.remove(msg_info)?;
663640
}
664641

665642
// 2. create our volume to copy all our data over to
@@ -673,13 +650,9 @@ pub(crate) fn run(
673650
.image
674651
.platform
675652
.specify_platform(&options.engine, &mut docker);
676-
docker.args(["--name", &container]);
653+
docker.args(["--name", &container_id]);
677654
docker.arg("--rm");
678-
let volume_mount = match volume {
679-
VolumeId::Keep(ref id) => format!("{id}:{mount_prefix}"),
680-
VolumeId::Discard => mount_prefix.to_owned(),
681-
};
682-
docker.args(["-v", &volume_mount]);
655+
docker.args(["-v", &volume.bind_mount(mount_prefix)]);
683656

684657
let mut volumes = vec![];
685658
docker_mount(
@@ -731,11 +704,11 @@ pub(crate) fn run(
731704
}
732705

733706
// store first, since failing to non-existing container is fine
734-
Container::create(engine.clone(), container.clone())?;
707+
ChildContainer::create(engine.clone(), container_id.clone())?;
735708
docker.run_and_get_status(msg_info, true)?;
736709

737710
// 4. copy all mounted volumes over
738-
let data_volume = DataVolume::new(engine, &container, toolchain_dirs);
711+
let data_volume = ContainerDataVolume::new(engine, &container_id, toolchain_dirs);
739712
let copy_cache = env::var("CROSS_REMOTE_COPY_CACHE")
740713
.map(|s| bool_from_envvar(&s))
741714
.unwrap_or_default();
@@ -903,7 +876,7 @@ symlink_recurse \"${{prefix}}\"
903876
));
904877
}
905878
subcommand_or_exit(engine, "exec")?
906-
.arg(&container)
879+
.arg(&container_id)
907880
.args(["sh", "-c", &symlink.join("\n")])
908881
.run_and_get_status(msg_info, false)
909882
.wrap_err("when creating symlinks to provide consistent host/mount paths")?;
@@ -913,7 +886,7 @@ symlink_recurse \"${{prefix}}\"
913886
docker_user_id(&mut docker, engine.kind);
914887
docker_envvars(&mut docker, &options, toolchain_dirs, msg_info)?;
915888
docker_cwd(&mut docker, &paths)?;
916-
docker.arg(&container);
889+
docker.arg(&container_id);
917890
docker.args(["sh", "-c", &build_command(toolchain_dirs, &cmd)]);
918891
bail_container_exited!();
919892
let status = docker
@@ -929,7 +902,10 @@ symlink_recurse \"${{prefix}}\"
929902
if !skip_artifacts && data_volume.container_path_exists(&target_dir, msg_info)? {
930903
subcommand_or_exit(engine, "cp")?
931904
.arg("-a")
932-
.arg(&format!("{container}:{}", target_dir.as_posix_absolute()?))
905+
.arg(&format!(
906+
"{container_id}:{}",
907+
target_dir.as_posix_absolute()?
908+
))
933909
.arg(
934910
package_dirs
935911
.target()
@@ -940,7 +916,7 @@ symlink_recurse \"${{prefix}}\"
940916
.map_err::<eyre::ErrReport, _>(Into::into)?;
941917
}
942918

943-
Container::finish_static(is_tty, msg_info);
919+
ChildContainer::finish_static(is_tty, msg_info);
944920

945921
status
946922
}

0 commit comments

Comments
 (0)