Skip to content
This repository has been archived by the owner on Oct 30, 2023. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Ruoss committed Dec 19, 2022
0 parents commit d8e013c
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: [mruoss]
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where third-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Ignore package tarball (built via "mix hex.build").
kino_k8s_term-*.tar

# Temporary files, for example, from tests.
/tmp/
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
erlang 25.1
elixir 1.14.2
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# KinoK8sTerm

**TODO: Add description**

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `kino_k8s_term` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[
{:kino_k8s_term, "~> 0.1.0"}
]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/kino_k8s_term>.

32 changes: 32 additions & 0 deletions assets/js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import "https://cdn.jsdelivr.net/npm/[email protected]/lib/xterm.min.js";

let k8s_xterm;

const openTerminal = (ctx) => {
k8s_xterm = new Terminal();
k8s_xterm.onKey((key) => {
console.log(key);
ctx.pushEvent("key", key.key);
});
k8s_xterm.open(ctx.root.querySelector(".k8s-xtermjs-container"));
k8s_xterm.focus();
};

export function init(ctx, attrs) {
ctx.importCSS("https://cdn.jsdelivr.net/npm/[email protected]/css/xterm.css");

ctx.root.innerHTML = `
<div id="k8s-terminal">
<div class="k8s-xtermjs-container"></div>
</div>
`;

if (attrs.term_pid) {
console.log("opening terminal");
setTimeout(() => openTerminal(ctx, 500));
}

ctx.handleEvent("open-terminal", () => openTerminal(ctx));
ctx.handleEvent("print-terminal", (data) => k8s_xterm.write(data));
ctx.handleEvent("dispose-terminal", () => k8s_xterm.dispose());
}
12 changes: 12 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Config

config :esbuild,
version: "0.16.9",
default: [
args:
~w(assets/js/main.js --target=es2016 --loader:.js=jsx --outdir=lib/assets/kino_k8s_term/)
],
watch: [
args:
~w(assets/js/main.js --target=es2016 --loader:.js=jsx --outdir=lib/assets/kino_k8s_term/ --sourcemap=inline --watch)
]
27 changes: 27 additions & 0 deletions lib/assets/kino_k8s_term/main.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 74 additions & 0 deletions lib/kino_k8s_term.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
defmodule KinoK8sTerm do
@moduledoc """
Documentation for `KinoK8sTerm`.
"""
use Kino.JS, assets_path: "lib/assets/kino_k8s_term"
use Kino.JS.Live
# use Kino.SmartCell, name: "Kubernetes Terminal"

def open(conn, namespace, pod, opts \\ []) do
ctx =
Kino.JS.Live.new(__MODULE__,
conn: conn,
namespace: namespace,
pod: pod,
container: Keyword.get(opts, :container),
command: Keyword.get(opts, :command, "/bin/sh")
)

Kino.JS.Live.cast(ctx, :open_terminal)
ctx
end

@impl true
def init(attrs, ctx) do
{:ok, assign(ctx, attrs)}
end

@impl true
def handle_connect(ctx) do
{:ok, %{}, ctx}
end

@impl true
def handle_cast(:open_terminal, ctx) do
{:ok, pid} =
Kino.start_child(
{KinoK8sTerm.PodConnector,
conn: ctx.assigns.conn,
namespace: ctx.assigns.namespace,
pod: ctx.assigns.pod,
container: ctx.assigns.container,
command: ctx.assigns.command,
stream_to: self()}
)

{:noreply, assign(ctx, term_pid: pid)}
end

@impl true
def handle_info(:open, ctx) do
broadcast_event(ctx, "open-terminal", nil)
{:noreply, ctx}
end

def handle_info({:stdout, data}, ctx) do
broadcast_event(ctx, "print-terminal", data)
{:noreply, ctx}
end

def handle_info(:close, ctx) do
broadcast_event(ctx, "dispose-terminal", nil)
{:noreply, assign(ctx, term_pid: nil)}
end

def handle_info(other_msg, ctx) do
{:noreply, ctx}
end

@impl true
def handle_event("key", key, ctx) do
send(ctx.assigns.term_pid, {:stdin, key})
{:noreply, ctx}
end
end
40 changes: 40 additions & 0 deletions lib/kino_k8s_term/pod_connector.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule KinoK8sTerm.PodConnector do
@spec child_spec(keyword()) :: Supervisor.child_spec()
def child_spec(args) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [args]},
restart: :transient
}
end

@spec start_link(keyword()) :: {:ok, pid}
def start_link(args) do
conn = Keyword.fetch!(args, :conn)
namespace = Keyword.fetch!(args, :namespace)
pod = Keyword.fetch!(args, :pod)
container = Keyword.fetch!(args, :container)
command = Keyword.fetch!(args, :command)
stream_to = Keyword.fetch!(args, :stream_to)

Task.start_link(__MODULE__, :run, [conn, namespace, pod, container, command, stream_to])
end

def run(conn, namespace, pod, container, command, stream_to) do
{:ok, stream} =
K8s.Client.connect(
"v1",
"pods/exec",
[namespace: namespace, name: pod],
container: container,
command: command,
tty: true
)
|> K8s.Client.put_conn(conn)
|> K8s.Client.stream()

stream
|> Stream.map(&send(stream_to, &1))
|> Stream.run()
end
end
30 changes: 30 additions & 0 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule KinoK8sTerm.MixProject do
use Mix.Project

def project do
[
app: :kino_k8s_term,
version: "0.1.0",
elixir: "~> 1.14",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
# mod: {KinoK8sTerm.Application, []},
extra_applications: [:logger]
]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:k8s, git: "https://github.com/coryodaniel/k8s.git", branch: "develop"},
{:esbuild, "~> 0.5", only: :dev},
{:kino, "~> 0.8.0"}
]
end
end
14 changes: 14 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%{
"castore": {:hex, :castore, "0.1.20", "62a0126cbb7cb3e259257827b9190f88316eb7aa3fdac01fd6f2dfd64e7f46e9", [:mix], [], "hexpm", "a020b7650529c986c454a4035b6b13a328e288466986307bea3aadb4c95ac98a"},
"esbuild": {:hex, :esbuild, "0.6.0", "9ba6ead054abd43cb3d7b14946a0cdd1493698ccd8e054e0e5d6286d7f0f509c", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "30f9a05d4a5bab0d3e37398f312f80864e1ee1a081ca09149d06d474318fd040"},
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
"k8s": {:hex, :k8s, "2.0.0-rc.0", "3cd38e615b0b63e57dbb570f4ed37d16af19d10df3f58e6953d4dabfcedf296f", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mint_web_socket, "~> 1.0", [hex: :mint_web_socket, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.8", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "5d4de30a96ed882803ce345ceabf92a89323ca07fc290631e8ad720c8f1d7532"},
"kino": {:hex, :kino, "0.8.0", "07603a32c111959ed48f08ac3808a0dda05433d28f8d2f06d65b25b255966649", [:mix], [{:nx, "~> 0.1", [hex: :nx, repo: "hexpm", optional: true]}, {:table, "~> 0.1.2", [hex: :table, repo: "hexpm", optional: false]}], "hexpm", "736568d4de9eb56d8903bae6fe08b7c06db44efe37bb883165e755e623881c51"},
"mint": {:hex, :mint, "1.4.2", "50330223429a6e1260b2ca5415f69b0ab086141bc76dc2fbf34d7c389a6675b2", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "ce75a5bbcc59b4d7d8d70f8b2fc284b1751ffb35c7b6a6302b5192f8ab4ddd80"},
"mint_web_socket": {:hex, :mint_web_socket, "1.0.2", "0933a4c82f2376e35569b2255cdce94f2e3f993c0d5b04c360460cb8beda7154", [:mix], [{:mint, ">= 1.4.0", [hex: :mint, repo: "hexpm", optional: false]}], "hexpm", "067c5e15439be060f2ab57c468ee4ab29e39cb20b498ed990cb94f62db0efc3a"},
"table": {:hex, :table, "0.1.2", "87ad1125f5b70c5dea0307aa633194083eb5182ec537efc94e96af08937e14a8", [:mix], [], "hexpm", "7e99bc7efef806315c7e65640724bf165c3061cdc5d854060f74468367065029"},
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
"yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"},
"yaml_elixir": {:hex, :yaml_elixir, "2.9.0", "9a256da867b37b8d2c1ffd5d9de373a4fda77a32a45b452f1708508ba7bbcb53", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "0cb0e7d4c56f5e99a6253ed1a670ed0e39c13fc45a6da054033928607ac08dfc"},
}
1 change: 1 addition & 0 deletions test/test_helper.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ExUnit.start()

0 comments on commit d8e013c

Please sign in to comment.