fussybeaver / bollard

Docker daemon API in Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`create_container` hanging

LittleAmara opened this issue · comments

Heyo,

In the code below I am trying to check if there is a container up on the machine, if not then I will create one and start it (which I did not include is the snippet as it is useless here) and I think I found an issue.

It seems that create_container hangs indefinitely in the tokio task. One way to fix it is to call another function like list_images but I am almost sure that this is not intended.

use bollard::{
    container::{Config, CreateContainerOptions},
    image::ListImagesOptions,
    Docker, API_DEFAULT_VERSION,
};
use crossbeam::channel::{unbounded, Receiver, Sender};
use tokio::join;
use tokio_schedule::{every, Job};

pub fn ensure(docker: Docker, id: u32, r: Receiver<u32>) -> tokio::task::JoinHandle<()> {
    tokio::task::spawn(async move {
        while let Ok(_) = r.recv() {
            println!("[{}] received message", id);

            let config = Config {
                image: Some("hello-world"),
                ..Default::default()
            };
            let options = Some(CreateContainerOptions {
                name: "hello",
                platform: None,
            });

            match &docker.create_container(options, config).await {
                item => println!("{:#?}", item),
            };

            // Uncomment here if you want to "fix"
            // let _ = &docker
            //     .list_images(Some(ListImagesOptions::<String> {
            //         all: true,
            //         ..Default::default()
            //     }))
            //     .await;
        }
    })
}

pub async fn browse(docker: &Docker, s: Sender<u32>) {
    join!(every(1).seconds().perform(|| async {
        println!("begin of browse");
        if docker.list_containers::<String>(None).await.unwrap().len() < 1 {
            println!("no countainer found, sending a message");
            s.send(0).expect("send failed");
        }
        println!("end of browse");
    }));
}

#[tokio::main]
async fn main() {
    let docker =
        Docker::connect_with_unix("unix:///var/run/docker.sock", 60, API_DEFAULT_VERSION).unwrap();

    let (sender, receiver) = unbounded();

    ensure(docker.clone(), 1, receiver.clone());
    browse(&docker, sender.clone()).await;
}

🤔 not sure, that looks unusual... a few things you could try is setup an env_logger and set the environment RUST_LOG=bollard=trace to see whether a request was made and it's waiting on something in your program. Also, put your docker daemon into debug mode and read the docker daemon logs, to check if a connection was made.

Hey, nothing that can help came out of the logs of both bollard and docker.

What I really do not understand is that calling whatever *_images functions does unlock the loop but calling info does not for example...

I had another look and tried executing the code -- it looks to me like the tokio_scheduler crate isn't scheduling another run when the docker client calls execute. It doesn't look like it hangs at that point though... Perhaps it's worth asking with the tokio_scheduler maintainer for any ideas.