softprops / shiplift

🐳 🦀 rust interface for maneuvering docker containers
MIT License
624 stars 119 forks source link

How to do something like `docker run` using shiplift? #314

Closed whereistejas closed 3 years ago

whereistejas commented 3 years ago

I have the following docker command that I want to run using shapelift:

docker run --name airbyte airbyte/source-postgres spec

Here, spec is an input command given to the image that we are going to run. The image expects an input the moment it is started.

So, if I try to do something like:

docker create --name airbyte airbyte/source-postgres 
docker start -a -i airbyte

I get the following error and the container exits:

command not specified.

How can I do something like this using shapelift?

This is the code I have written:

let docker = Docker::new();
let containers = docker.containers();
let images = docker.images();

let image_name = "airbyte/source-postgres".to_string();

let opts = PullOptions::builder()
    .image(&image_name)
    .tag("latest")
    .build();

println!("Pulling");

if let Ok(pull_result) = images.pull(&opts).try_collect::<Vec<_>>().await {
    println!("{:?}", pull_result);
} else {
    panic!("Could not pull the latest docker images from the internet.");
}

let opts = ContainerListOptions::builder().build();

match containers.list(&opts).await {
    Ok(list_containers) => println!("{:?}", list_containers),
    Err(_) => panic!("Could not fetch the list of docker containers in the current system."),
}

let opts = ContainerOptions::builder(&image_name).build();

let mut container_id = String::new();

if let Ok(create_result) = containers.create(&opts).await {
    println!("{:?}", create_result.id);
    container_id = create_result.id;
} else {
    panic!("Could not create the docker container in the current system.");
}

let container = containers.get(&container_id);

match container.start().await {
    Ok(info) => println!("{:?}", info),
    Err(e) => println!("{:?}", e),
}

let opts = ExecContainerOptions::builder()
    .attach_stdout(true)
    .cmd(vec!["spec"])
    .build();

match container.exec(&opts).try_collect::<Vec<_>>().await {
    Ok(info) => println!("{:?}", info),
    Err(e) => println!("{:?}", e),
}

However the exec command fails with the following message:

Fault { code: 409, message: "Container d2197cae064824c9941bc8743d937ac97a7db22debe842c66fa4a069ee0cf67f is not running" }

This is as we expected because the container exits the moment we create it. Can someone suggest me a workaround for this?

whereistejas commented 3 years ago

Hi, I solved this issue. For anyone coming here look for the same solution refer this file.