Skip to content

Commit

Permalink
Add pod_shell example
Browse files Browse the repository at this point in the history
  • Loading branch information
kazk committed Jan 2, 2021
1 parent 698321a commit f429593
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
4 changes: 4 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ path = "pod_attach.rs"
name = "pod_exec"
path = "pod_exec.rs"

[[example]]
name = "pod_shell"
path = "pod_shell.rs"

[[example]]
name = "proxy"
path = "proxy.rs"
Expand Down
90 changes: 90 additions & 0 deletions examples/pod_shell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#[macro_use]
extern crate log;

use futures::{StreamExt, TryStreamExt};
use k8s_openapi::api::core::v1::Pod;

use kube::{
api::{Api, AttachParams, DeleteParams, ListParams, Meta, PostParams, WatchEvent},
Client,
};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
std::env::set_var("RUST_LOG", "info,kube=debug");
env_logger::init();
let client = Client::try_default().await?;
let namespace = std::env::var("NAMESPACE").unwrap_or_else(|_| "default".into());

let p: Pod = serde_json::from_value(serde_json::json!({
"apiVersion": "v1",
"kind": "Pod",
"metadata": { "name": "example" },
"spec": {
"containers": [{
"name": "example",
"image": "alpine",
// Do nothing
"command": ["tail", "-f", "/dev/null"],
}],
}
}))?;

let pods: Api<Pod> = Api::namespaced(client, &namespace);
// Stop on error including a pod already exists or is still being deleted.
pods.create(&PostParams::default(), &p).await?;

// Wait until the pod is running, otherwise we get 500 error.
let lp = ListParams::default().fields("metadata.name=example").timeout(10);
let mut stream = pods.watch(&lp, "0").await?.boxed();
while let Some(status) = stream.try_next().await? {
match status {
WatchEvent::Added(o) => {
info!("Added {}", Meta::name(&o));
}
WatchEvent::Modified(o) => {
let s = o.status.as_ref().expect("status exists on pod");
if s.phase.clone().unwrap_or_default() == "Running" {
info!("Ready to attach to {}", Meta::name(&o));
break;
}
}
_ => {}
}
}

// Piping current stdin/stdout
{
let mut attached = pods
.exec(
"example",
vec!["sh"],
&AttachParams::default()
.stdin(true)
.stdout(true)
.stderr(false)
.tty(true),
)
.await?;
let mut stdin_writer = attached.stdin().unwrap();
let mut stdout_reader = attached.stdout().unwrap();
// > For interactive uses, it is recommended to spawn a thread dedicated to user input and use blocking IO directly in that thread.
// > https://docs.rs/tokio/0.2.24/tokio/io/fn.stdin.html
let mut stdin = tokio::io::stdin();
let mut stdout = tokio::io::stdout();
futures::join!(
tokio::io::copy(&mut stdin, &mut stdin_writer),
tokio::io::copy(&mut stdout_reader, &mut stdout)
);
}

// Delete it
println!("deleting");
pods.delete("example", &DeleteParams::default())
.await?
.map_left(|pdel| {
assert_eq!(Meta::name(&pdel), "example");
});

Ok(())
}

0 comments on commit f429593

Please sign in to comment.