1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use crate::{
    conn::{tty, Headers, Payload},
    opts,
    util::url,
    Result,
};

use futures_util::future::TryFutureExt;
use futures_util::stream::Stream;

impl_api_ty!(Exec => id);

impl<'podman> Exec<'podman> {
    api_doc! {
    Exec => StartLibpod
    /// Starts a previously set up exec instance. If `detach` is true, this endpoint returns
    /// immediately after starting the command. Otherwise, it sets up an interactive session
    /// with the command.
    ///
    /// To create an exec instance use [`Container::create_exec`](crate::api::Container::create_exec).
    ///
    /// Examples:
    ///
    /// ```no_run
    /// use futures_util::StreamExt;
    /// let podman = Podman::unix("/run/user/1000/podman/podman.sock");
    /// let container = podman.containers().get("451b27c6b9d3");
    ///
    /// let exec = container
    ///     .create_exec(
    ///         &podman_api::opts::ExecCreateOpts::builder()
    ///             .command(["cat", "/some/path/in/container"])
    ///             .build(),
    ///     )
    ///     .await
    ///     .unwrap();
    ///
    /// let stream = exec.start();
    ///
    /// while let Some(chunk) = stream.next().await {
    ///     println!("{:?}", chunk.unwrap());
    /// }
    /// ```
    |
    pub fn start(
        &'podman self,
        opts: &'podman opts::ExecStartOpts,
    ) -> impl Stream<Item = Result<tty::TtyChunk>> + 'podman {
        let ep = format!("/libpod/exec/{}/start", &self.id);
        Box::pin(
            async move {
                let payload = Payload::Json(opts.serialize()?);
                let stream = Box::pin(self.podman.stream_post(ep, payload, Headers::none()));

                Ok(tty::decode(stream))
            }
            .try_flatten_stream(),
        )
    }}

    api_doc! {
    Exec => InspectLibpod
    /// Returns low-level information about an exec instance.
    ///
    /// Examples:
    ///
    /// ```no_run
    /// use futures_util::StreamExt;
    /// let podman = Podman::unix("/run/user/1000/podman/podman.sock");
    /// let container = podman.containers().get("451b27c6b9d3");
    ///
    /// let exec = container
    ///     .create_exec(
    ///         &podman_api::opts::ExecCreateOpts::builder()
    ///             .command(["cat", "/some/path/in/container"])
    ///             .build(),
    ///     )
    ///     .await
    ///     .unwrap();
    ///
    /// match exec.inspect().await {
    ///     Ok(info) => println!("{:?}", info),
    ///     Err(e) => eprintln!("{}", e)
    /// }
    /// ```
    |
    pub async fn inspect(
        &self,
    ) -> Result<serde_json::Value> {
        let ep = format!("/libpod/exec/{}/json", &self.id);
        self.podman.get_json(&ep).await
    }}

    api_doc! {
    Exec => ResizeLibpod
    /// Resize the TTY session used by an exec instance. This endpoint only works if
    /// tty was specified as part of creating and starting the exec instance.
    ///
    /// Examples:
    ///
    /// ```no_run
    /// use futures_util::StreamExt;
    /// let podman = Podman::unix("/run/user/1000/podman/podman.sock");
    /// let container = podman.containers().get("451b27c6b9d3");
    ///
    /// let exec = container
    ///     .create_exec(
    ///         &podman_api::opts::ExecCreateOpts::builder()
    ///             .command(["cat", "/some/path/in/container"])
    ///             .build(),
    ///     )
    ///     .await
    ///     .unwrap();
    ///
    /// if let Err(e) = exec.resize(1280, 720).await {
    ///     eprintln!("{}", e);
    /// }
    /// ```
    |
    pub async fn resize(&self, width: usize, heigth: usize) -> Result<()> {
        let ep = url::construct_ep(
            format!("/libpod/exec/{}/resize", &self.id),
            Some(url::encoded_pairs([
                ("h", heigth.to_string()),
                ("w", width.to_string()),
            ])),
        );
        self.podman.get_json(&ep).await
    }}
}