5 releases (breaking)

0.5.0 Apr 17, 2023
0.4.0 Jan 13, 2023
0.3.0 Sep 5, 2022
0.2.0 May 8, 2022
0.1.0 Mar 18, 2022

#579 in Development tools

MIT/Apache

225KB
5.5K SLoC

podtender logo

Podtender

An async rust client library for the Podman REST API.

Crates.io Documentation

Usage

Example

use tokio;
use podtender::podman_service::PodmanService;

#[tokio::main]
async fn main() {
  let podman_service = PodmanService::new("path/to/podman/socket");
  let podtender_result = podman_service.system().get_info().await.unwrap();
  println!("{podtender_result:?}");
}

The integration tests also act as examples for how to use the crate.

Podman setup

The Podman service needs to be set up before the crate can be used.

# Set up podman service
podman system service unix:///home/`whoami`/podman.sock --log-level=debug --time=50
# Test if the socket is up and running
curl --unix-socket /home/`whoami`/podman.sock http://d/v4.0.0/libpod/info

Supported Podman version

We aim to support the latest Podman version only. Currently, this is 4.5.x.

Crate features

Builder pattern via derive builder

The builder feature enables the builder pattern for request types. This is implemented with the builder derive macro. IDE support for code created by macros may be limited.

// with builder feature
let create_volume_parameter = CreateVolumeParameterBuilder::default()
    .driver("local".to_owned())
    .volume_name("some_volume_name".to_owned())
    .options(some_previously_created_hashmap)
    .build()
    .expect("Error building CreateVolumeParameter");
// without builder feature
let create_volume_parameter = CreateVolumeParameter {
    driver: Some("local".to_owned()),
    labels: None,
    volume_name: Some("some_volume_name".to_owned())
    options: Some(some_previously_created_hashmap),
}

Example parameters used in tests

The examples feature enables initialized parameters via the ExampleValues trait. This is mostly intended for tests and to showcase a usable example parameter per API operation.

Tracing

tracing enables logs/tracing powered by Tokio's tracing crate.

Requirements

Podtender uses hyper and requires tokio. An active Podman socket is needed to communicate with Podman.

Tests

To run the integration tests, the tracing and examples features are required. To allow easy testing, the tests are defined as target in the Cargo.toml file and can be run with cargo test --test {target-name} --features="examples tracing" where {target-name} is one of the specified targets (e.g. containers-test).

Project structure

The Podman socket and network operations are internally managed by the PodmanService struct.

The Podman API categorizes endpoints into multiple sections. This crate is based on that structure. The pods module contains all api call functions, parameter types and response types for the implemented pods API endpoints.

Every endpoint category module contains:

  • the parameter types, used to configure the request
  • the api call functions used to make the request
  • the response types into which the response gets deserialized

To start a pod, you would configure podtender::pods::parameter_types::PodStatsParameter use it with podman_service.pods().start(parameter).await and expect podtender::pods::response_types::StartPodResponse.

Notes

  • Only unix socket is currently supported
  • Podtender currently only builds on Linux since tokio only builds support for unix sockets on Linux
  • Podman (API) is treated as trusted and in testing as source of truth
  • To create a container in bridge network mode, use this as starting point:
    CreateContainerParameter {
          netns: Some(Namespace {
              nsmode: Some("bridge".to_owned()),
              value: None,
          }),
          ..Default::default()
      };
    
  • The following error indicates the Podman socket not being available. If this happens in tests, rerunning recreates the socket for the defined ttl and should get rid of the error.
     HyperError(
         hyper::Error(
             Connect,
             Os {
                 code: 2,
                 kind: NotFound,
                 message: "No such file or directory",
             },
         ),
     )
    
  • The connect_container_to_network_from_example test require the 192.168.123.0/24 subnet to be unused on the machine executing the tests.
  • 2021-05-26T10:42:00+02:00 timestamps are supported by Podman, this crate currently only supports dates as strings.
  • Podman only supports query array in this format: containers=container1&containers=container2
  • Tests create the Podman service socket at unix:///home/{user}/{socket_name}.sock, the socket_name can be changed in tests/utils.
  • Tests build images from the Dockerfiles in test_container.

Acknowledgments

  • This work was created at Science and Technology for Peace and Security (PEASEC), Technical University of Darmstadt, www.peasec.de, and supported by funds of the German Government’s Special Purpose Fund held at Landwirtschaftliche Rentenbank in the projects Geobox-II and AgriRegio.
    • Contributors under those funds:
      • Julian Schindel
      • Franz Kuntke
  • The overall structure of this crate was inspired by shiplift, created by softprops (Doug Tangren).

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in podtender by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Current State

Currently supported API endpoints:

  • Containers
    • Commit
    • Delete Container
    • Copy files into a Container
    • Attach to a container
    • Report on changes to the container's filesystem; adds, deletes or modifications
    • Checkpoint a container (currently not tested, CRIU requires root privileges)
    • Check if a container exists
    • Export a container
    • Run a container's healtcheck
    • Initialize a container
    • Inspect container
    • Kill container
    • Get container logs
    • Mount a container
    • Pause a container
    • Rename an existing container
    • Resize a Container's TTY
    • Restart a container
    • Restore a container
    • Start a container
    • Get stats for a container (deprecated, use "Get stats for one or more containers")
    • Stop a container
    • List processes
      • streaming
      • non streaming
    • Unmount a container
    • Unpause container
    • Wait on a container
    • Create a container
    • List containers
    • Delete stopped containers
    • Show mounted containers
    • Get stats for one or more containers
      • streaming
      • non streaming
    • Generate a Kubernetes YAML file
    • Remove pods from play kube
    • Play a Kubernetes YAML file
  • exec
    • Create an exec instance
    • Inspect an exec instance
    • Resize an exec instance
    • Start an exec instance
  • images
    • Create image
    • Remove an image from the local storage
    • Report on changes to image's filesystem; adds, deletes or modifications
    • Image exists
    • Export an image
    • History of an image
    • Inspect an Image
    • Push image
    • Tag an image
    • Image tree
    • Untag an image
    • Export multiple images
    • Import image
    • List images
    • Load image
    • Prune unused images
    • Pull images
    • Remove one or more images from the storage
    • Search images
  • manifests
    • Remove
    • Add image
    • Exists
    • Inspect
    • Push
    • Create
  • networks
    • Remove a network
    • Connect container to network
    • Disconnect container from network
    • Network exists
    • Inspect a network
    • Create network
    • List networks
    • Delete unused networks
  • pods
    • Generate Systemd Units
    • Generate a Kubernetes YAML file
    • Remove pod
    • Pod exists
    • Inspect pod
    • Kill a pod
    • Pause a pod
    • Restart a pod
    • Start a pod
    • Stop a pod
    • List processes
      • streaming
      • non streaming
    • Unpause a pod
    • Create a pod
    • List pods
    • Prune unused pods
    • Get stats for one or more pods
  • volumes
    • Remove volume
    • Volume exists
    • Inspect volume
    • Create a volume
    • List volumes
    • Prune volumes
  • secrets
    • Remove secret
    • Inspect secret
    • Create secret
    • List secrets
  • system
    • Ping service
    • Get events
      • streaming
      • non streaming
    • Get info
    • Show disk usage
    • Prune unused data
    • Component version information

Planned features

  • Support DateTime Json fields (currently represented as String)
  • Full support of the Podman API (Docker compat is out of scope)

Dependencies

~6–17MB
~201K SLoC