Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Commit 8e3cd4f

Browse files
committed
working version
1 parent 2aa1844 commit 8e3cd4f

File tree

8 files changed

+85
-52
lines changed

8 files changed

+85
-52
lines changed

additional_bash_commands.sh

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
alias get_java_pid='ps aux | grep java | grep -v grep | cut -d" " -f6'
2-
alias push_jdk='mkdir -p /proc/$(ps aux | grep java | grep -v grep | cut -d" " -f6)/cwd/mnt/robusta;\
3-
cp -r /app/openjdk /proc/$(ps aux | grep java | grep -v grep | cut -d" " -f6)/cwd/mnt/robusta'
4-
alias cleanup='rm -r /proc/$(ps aux | grep java | grep -v grep | cut -d" " -f6)/cwd/mnt/robusta'
5-
alias podns_shell='nsenter -t $(ps aux | grep java | grep -v grep | cut -d" " -f6) -m -p /bin/sh'
2+
alias push_jdk='mkdir -p /proc/$PID/cwd/mnt/robusta;\
3+
cp -r /app/openjdk /proc/$PID/cwd/mnt/robusta'
4+
alias cleanup='rm -r /proc/$PID/cwd/mnt/robusta'
5+
alias podns_shell='nsenter -t $PID -m -p /bin/sh'
6+
7+
alias push_jdk='mkdir -p /proc/$PID/cwd/mnt/robusta;\
8+
cp -r /app/openjdk* /proc/$PID/cwd/mnt/robusta'
69

710
function nsjdk(){
8-
local NSENTER_CMD='nsenter -t $(ps aux | grep java | grep -v grep | cut -d" " -f6) -m -p /mnt/robusta/openjdk/bin/'
11+
local NSENTER_CMD='nsenter -t $PID -m -p /mnt/robusta/openjdk/bin/'
912
COMMAND=""
1013
if [ "$1" = "jmap" ]; then COMMAND="jmap $2";
1114
elif [ "$1" = "jstack" ]; then COMMAND="java-toolkit jstack $2";

dockerfile

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ WORKDIR /app/
1212
RUN /root/.local/bin/poetry install --no-interaction --no-root
1313

1414
COPY src /app/src
15+
1516
RUN /root/.local/bin/poetry install
1617
RUN cat additional_bash_commands.sh >> ~/.bashrc
17-
COPY --from=adoptopenjdk/openjdk11-openj9:ppc64le-ubuntu-jdk-11.0.14_9_openj9-0.30.0 /opt/java/openjdk /app/openjdk
18+
#COPY jdk_11_9 /app/openjdk3
19+
COPY --from=openjdk:11.0.14-jdk /usr/local/openjdk-11 /app/openjdk
20+
#COPY --from=adoptopenjdk/openjdk11-openj9:jdk-11.0.14_9_openj9-0.30.0-alpine /opt/java/openjdk /app/openjdk2
21+
1822
CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"
1923

2024
#run on jenkens

src/java_toolkit/common/utils/processes.py renamed to src/java_toolkit/common/utils/process.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
r"\d+:.+:/kubepods\.slice/kubepods-[^/]+\.slice/kubepods-[^/]+-pod([^/]+)\.slice/docker-([0-9a-f]{64})"
1616
)
1717

18-
ps_regex = re.compile(r"\s*(?P<pid>.*?)\s+(?P<cmd>.*?)\s+(?P<cmd_args>.*?)\n")
18+
ps_regex = re.compile(r"\s*(?P<pid>.*?)\s+(?P<cmd>.*?)\s+(?P<cmd_args>.*?)$")
1919

2020
app = typer.Typer()
2121

@@ -64,16 +64,21 @@ def get_pod_processes(pod_uid: str) -> ProcessList:
6464
processes.append(Process(pid=pid, exe=proc.exe(), cmdline=proc.cmdline()))
6565
return ProcessList(processes=processes)
6666

67+
def get_pid_info(pid: int) -> Process:
68+
proc = psutil.Process(pid)
69+
return Process(pid=pid, exe=proc.exe(), cmdline=proc.cmdline())
70+
6771
def get_ns_processes(pid_in_ns: int, verbose: bool):
68-
cmd = "ps -o pid,comm,args | tail -n +2 "
72+
cmd = "ps -Ao pid,comm,args | grep -v PID"
6973
processes = run_cmd_in_proc_namespace(pid_in_ns, cmd, verbose)
7074
processes = processes.split('\n')
7175
return_proc_list=[]
72-
processes.remove(processes[0]) #title column
7376
for proc_line in processes:
74-
if "tail -n" in proc_line or "ps -o pid,comm,args" in proc_line:
77+
if not proc_line:
7578
continue
7679
match = ps_regex.match(proc_line)
80+
if not match:
81+
continue
7782
pid = int(match.group("pid"))
7883
exe = match.group("cmd")
7984
cmdline = match.group("cmd_args")
@@ -82,7 +87,7 @@ def get_ns_processes(pid_in_ns: int, verbose: bool):
8287
else:
8388
cmdline = cmdline.split(' ')
8489
return_proc_list.append(Process(pid=pid, exe=exe, cmdline=cmdline))
85-
return return_proc_list
90+
return ProcessList(processes=return_proc_list)
8691

8792

8893

src/java_toolkit/common/utils/remote_ns_cmd.py

+4-11
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,11 @@
55
def run_command(cmd: str, verbose: bool):
66
if verbose:
77
typer.echo(f"Running {cmd}")
8-
proc = subprocess.Popen(
9-
cmd, shell=True, stdin=subprocess.PIPE, stderr=subprocess.STDOUT
10-
)
11-
(output, err) = proc.communicate()
12-
13-
proc.stdout.close()
14-
return_code = proc.wait()
15-
if return_code:
16-
raise subprocess.CalledProcessError(return_code, cmd)
8+
output = subprocess.check_output(
9+
cmd, shell=True, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
1710
if verbose:
18-
typer.echo(output)
19-
return output, err
11+
typer.echo(f"output recieved: \n{output.decode()}")
12+
return output.decode()
2013

2114
def run_cmd_in_proc_namespace(pid, command_to_run, verbose):
2215
NSENTER_CMD = "nsenter -t {} -p -m {}"

src/java_toolkit/common/utils/tmp_mount.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .remote_ns_cmd import run_command
2-
from os.path import join, basename
2+
from os import path
33

44
class TmpRemotePodMounter(object):
55
remote_mnt_path =""
@@ -9,13 +9,13 @@ class TmpRemotePodMounter(object):
99
MKDIR_POD_CMD="mkdir -p {}"
1010
RMDIR_POD_CMD="rm -R {}"
1111
COPY_CMD="cp -R {} {}"
12-
ROOT_PROC_NS="/proc/{}/cwd",
12+
ROOT_PROC_NS="/proc/{}/cwd{}"
1313

1414
def __init__(self, pid: str, src_dir: str, local_mnt_path: str, verbose: bool):
1515
self.verbose = verbose
1616
self.src_dir = src_dir
1717
self.local_mnt_path = local_mnt_path
18-
self.remote_mnt_path = join(self.ROOT_PROC_NS.format(pid), local_mnt_path)
18+
self.remote_mnt_path = self.ROOT_PROC_NS.format(pid,local_mnt_path)
1919

2020
def __enter__(self):
2121
mkdir_cmd = self.MKDIR_POD_CMD.format(self.remote_mnt_path)
@@ -25,7 +25,7 @@ def __enter__(self):
2525
return self
2626

2727
def get_mounted_jdk_dir(self):
28-
return join(self.local_mnt_path, basename(self.src_dir) )
28+
return path.join(self.local_mnt_path, path.basename(self.src_dir) )
2929

3030
def __exit__(self, exc_type, exc_val, exc_tb):
3131
rm_dir_cmd = self.RMDIR_POD_CMD.format(self.remote_mnt_path)

src/java_toolkit/configs.json

-8
This file was deleted.

src/java_toolkit/configs.py

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
##### PATHS ####
2+
"""
3+
JDK_PATH is the path our docker image stores the jdk. if you would like to change this you also will have to update
4+
your dockerfile. For multiple jdk versions you will need a different JDK_PATH for each one.
5+
6+
LOCAL_MOUNT_PATH is the path the jdk will be temporary saved on to your pod
7+
"""
18
JDK_PATH= "/app/openjdk"
29
LOCAL_MOUNT_PATH= "/mnt/robusta"
3-
JDK_NAME= "openjdk"
4-
JMAP_CMD= "{}/bin/jmap -J-Xshareclasses:nonfatal -histo:live {}"
5-
JSTACK_CMD= "{}/bin/jstack -J-Xshareclasses:nonfatal -l {}"
10+
11+
##### JDK COMMANDS####
12+
"""
13+
they need the variable {jdk_path} in the command
14+
if it requires a pid add it in the {pid} field
15+
any flags the command needs add to the command itself
16+
"""
17+
JMAP_CMD= "{jdk_path}/bin/jmap -histo:live {pid}"
18+
JSTACK_CMD= "{jdk_path}/bin/jstack -l {pid}"

src/java_toolkit/main.py

+38-15
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,57 @@
11
#!/usr/local/bin/python3
22
import subprocess
33
import typer
4-
from .utils.process import get_pod_processes, get_ns_processes
5-
from .utils.remote_ns_cmd import run_cmd_in_proc_namespace
6-
from .utils.tmp_mount import TmpRemotePodMounter
4+
from .common.utils.process import *
5+
from .common.utils.remote_ns_cmd import run_cmd_in_proc_namespace
6+
from .common.utils.tmp_mount import TmpRemotePodMounter
77
from .configs import *
8-
from os.path import join
98

109
app = typer.Typer()
1110

11+
def get_matching_local_pid(pid: int, verbose: bool):
12+
process_cmd = ' '.join(get_pid_info(pid).cmdline)
13+
ns_processes = get_ns_processes(pid, verbose)
14+
process_list = []
15+
for ns_process in ns_processes.processes:
16+
ns_process_cmd = ' '.join(ns_process.cmdline)
17+
if process_cmd == ns_process_cmd:
18+
process_list.append(ns_process)
19+
if len(process_list) != 1:
20+
raise Exception(f"{len(process_list)} match the pid {pid} args '{process_cmd}'")
21+
return process_list[0].pid
22+
23+
def run_jdk_cmd(pid: int, cmd_missing_jdk_path:str, add_local_pid: bool, verbose: bool):
24+
with TmpRemotePodMounter(pid, JDK_PATH, LOCAL_MOUNT_PATH, verbose) as jdk_mounter:
25+
cmd = cmd_missing_jdk_path
26+
if add_local_pid:
27+
local_pid = get_matching_local_pid(pid, verbose)
28+
cmd = cmd.format(jdk_path=jdk_mounter.get_mounted_jdk_dir(),pid=local_pid)
29+
else:
30+
cmd = cmd.format(jdk_path=jdk_mounter.get_mounted_jdk_dir())
31+
output = run_cmd_in_proc_namespace(pid, cmd, verbose)
32+
typer.echo(output)
33+
34+
1235
@app.command()
1336
def pod_ps(pod_uid: str):
14-
app.echo(get_pod_processes(pod_uid).json())
37+
typer.echo(get_pod_processes(pod_uid).json())
38+
1539

1640
@app.command()
17-
def pod_ns_ps(pid: str, verbose: bool = True):
18-
app.echo(get_ns_processes(pid, verbose).json())
41+
def pod_ns_ps(pid: int, verbose: bool = False):
42+
typer.echo(get_ns_processes(pid, verbose).json())
43+
1944

2045
@app.command()
21-
def jmap(pid: int, verbose: bool = True):
22-
with TmpRemotePodMounter(pid, JDK_PATH, LOCAL_MOUNT_PATH, verbose) as jdk_mounter:
23-
jstack_cmd = JMAP_CMD.format(jdk_mounter.get_mounted_jdk_dir(), 1)
24-
run_cmd_in_proc_namespace(pid, jstack_cmd, verbose)
46+
def jmap(pid: int, verbose: bool = False):
47+
run_jdk_cmd(pid, JMAP_CMD, add_local_pid=True, verbose=verbose)
48+
2549

2650

2751
@app.command()
28-
def jstack(pid: int, verbose: bool = True):
29-
with TmpRemotePodMounter(pid, JDK_PATH, LOCAL_MOUNT_PATH, verbose) as jdk_mounter:
30-
jstack_cmd = JSTACK_CMD.format(jdk_mounter.get_mounted_jdk_dir(), 1)
31-
run_cmd_in_proc_namespace(pid, jstack_cmd, verbose)
52+
def jstack(pid: int, verbose: bool = False):
53+
run_jdk_cmd(pid, JSTACK_CMD, add_local_pid=True, verbose=verbose)
54+
3255

3356
if __name__ == "__main__":
3457
app()

0 commit comments

Comments
 (0)