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
use std::error::Error;

use ntex::util::Bytes;
use ntex::channel::mpsc::Receiver;
use futures::Stream;

use nanocl_error::http::HttpResult;
use nanocl_error::http_client::HttpClientResult;

use nanocl_stubs::vm_image::{VmImage, VmImageCloneStream, VmImageResizePayload};

use crate::NanocldClient;

impl NanocldClient {
  /// ## Default path for vm images
  const VM_IMAGE_PATH: &'static str = "/vms/images";

  /// This method will import a vm image from a stream of bytes.
  pub async fn import_vm_image<S, E>(
    &self,
    name: &str,
    stream: S,
  ) -> HttpClientResult<()>
  where
    S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
    E: Error + 'static,
  {
    self
      .send_post_stream(
        &format!("{}/{name}/import", Self::VM_IMAGE_PATH),
        stream,
        None::<String>,
      )
      .await?;
    Ok(())
  }

  /// List existing vm images in the system.
  ///
  /// ## Example
  ///
  /// ```no_run,ignore
  /// use nanocld_client::NanocldClient;
  ///
  /// let client = NanocldClient::connect_to("http://localhost:8585", None);
  /// let res = client.list_vm_image().await;
  /// ```
  pub async fn list_vm_image(&self) -> HttpClientResult<Vec<VmImage>> {
    let res = self.send_get(Self::VM_IMAGE_PATH, None::<String>).await?;
    Self::res_json(res).await
  }

  /// Delete a vm image by it's name
  ///
  /// ## Example
  ///
  /// ```no_run,ignore
  /// use nanocld_client::NanocldClient;
  ///
  /// let client = NanocldClient::connect_to("http://localhost:8585", None);
  /// let res = client.delete_vm_image("my-image").await;
  /// ```
  pub async fn delete_vm_image(&self, name: &str) -> HttpClientResult<()> {
    self
      .send_delete(&format!("{}/{name}", Self::VM_IMAGE_PATH), None::<String>)
      .await?;
    Ok(())
  }

  /// Clone a vm image by it's name
  ///
  /// ## Example
  ///
  /// ```no_run,ignore
  /// use nanocld_client::NanocldClient;
  ///
  /// let client = NanocldClient::connect_to("http://localhost:8585", None);
  /// let res = client.clone_vm_image("my-image", "my-clone").await;
  /// ```
  pub async fn clone_vm_image(
    &self,
    name: &str,
    clone_name: &str,
  ) -> HttpClientResult<Receiver<HttpResult<VmImageCloneStream>>> {
    let res = self
      .send_post(
        &format!("{}/{name}/clone/{clone_name}", Self::VM_IMAGE_PATH),
        None::<String>,
        None::<String>,
      )
      .await?;
    Ok(Self::res_stream(res).await)
  }

  /// Resize a vm image by it's name
  ///
  /// ## Example
  ///
  /// ```no_run,ignore
  /// use nanocld_client::NanocldClient;
  ///
  /// let client = NanocldClient::connect_to("http://localhost:8585", None);
  /// let res = client.resize_vm_image("my-image", VmImageResizePayload {
  ///   size: 45640,
  ///   shrink: false,
  /// }).await;
  /// ```
  pub async fn resize_vm_image(
    &self,
    name: &str,
    opts: &VmImageResizePayload,
  ) -> HttpClientResult<VmImage> {
    let res = self
      .send_post(
        &format!("{}/{name}/resize", Self::VM_IMAGE_PATH),
        Some(opts.clone()),
        None::<String>,
      )
      .await?;
    Self::res_json(res).await
  }
}