Skip to content

Commit

Permalink
Added cp utility for pods
Browse files Browse the repository at this point in the history
  • Loading branch information
Jiri Otoupal committed Nov 15, 2023
1 parent bee2241 commit fabb195
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 13 deletions.
2 changes: 1 addition & 1 deletion abst/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"CLI Command making OCI Bastion and kubernetes usage simple and fast"
)

__version__ = "2.3.4"
__version__ = "2.3.5"
__author__ = "Jiri Otoupal"
__author_email__ = "jiri-otoupal@ips-database.eu"
__license__ = "MIT"
Expand Down
26 changes: 14 additions & 12 deletions abst/cli_commands/cp_cli/commands.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import logging
import os
import re
from pathlib import Path
from subprocess import call

import click
import rich
from InquirerPy import inquirer

from abst.utils.misc_funcs import setup_calls, fetch_pods
from abst.utils.misc_funcs import setup_calls, fetch_pods, recursive_copy


@click.group("cp", help="Copy commands for special usage")
Expand Down Expand Up @@ -50,11 +51,12 @@ def cp_secret(


@cp.command("file", help="Will copy file into pod with containing string name")
@click.argument("pod_name")
@click.argument("local_path")
@click.argument("dest_path")
@click.argument("pod_name", type=str)
@click.argument("local_path", type=str)
@click.argument("dest_path", type=str)
@click.option("--exclude", default="", type=str)
@click.option("--debug", is_flag=True, default=False)
def cp_to_pod(pod_name, local_path, dest_path, debug):
def cp_to_pod(pod_name, local_path, dest_path, exclude, debug):
setup_calls(debug)

try:
Expand Down Expand Up @@ -94,11 +96,11 @@ def cp_to_pod(pod_name, local_path, dest_path, debug):
rich.print("[red]Failed to copy using conventional kubectl cp, probably missing [yellow]tar[/yellow] "
"executable[/red]")
rich.print("[yellow]Trying alternative copy method...[/yellow]")
kubectl_alt_copy_cmd = (f"cat {local_path} |"
f" kubectl exec -i {pod_name_precise} -n {data[0]} -- tee {dest_path} > /dev/null")
logging.info(f"Executing {kubectl_alt_copy_cmd}")
exit_code = os.system(kubectl_alt_copy_cmd)
if exit_code == 0:
rich.print("[green]File successfully copied![/green]")
else:
rich.print("[red]Failed.[/red]")
return
local_path_obj = Path(local_path).expanduser().resolve()
thread_list = []
recursive_copy(local_path_obj, dest_path, exclude, data, pod_name_precise, thread_list)

for t in thread_list:
t.join()
53 changes: 53 additions & 0 deletions abst/utils/misc_funcs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import json
import logging
import os
import subprocess
from pathlib import Path
from threading import Thread
from time import sleep
from typing import Optional

import rich
Expand Down Expand Up @@ -63,3 +66,53 @@ def fetch_pods():
.split("\n")
)
return pod_lines


def recursive_copy(dir_to_iter: Path, dest_path: str, exclude: str, data: list, pod_name_precise: str,
thread_list: list):
for file in dir_to_iter.iterdir():
final_dest_path = make_final_dest_path(dest_path, file)
if file.name == exclude:
rich.print(f" [yellow]{file} excluded.[/yellow]")
continue
elif file.is_dir():
rich.print(f"[yellow]Recursion to folder {file}[/yellow]")

create_folder_kubectl(data, final_dest_path, pod_name_precise)
t = Thread(name=f"recursive_copy_{file}", target=recursive_copy,
args=[file, dest_path, exclude, data, pod_name_precise, thread_list])
t.start()
thread_list.append(t)
else:
copy_file_alt_kubectl(data, final_dest_path, file, pod_name_precise)


def make_final_dest_path(dest_path, file):
sub_path = str(file).split("/")

fsp = sub_path[sub_path.index(Path(dest_path).name) + 1:]

final_dest_path = f"{dest_path}{'/' if len(fsp) > 0 else ''}{'/'.join(fsp)}"
return final_dest_path


def create_folder_kubectl(data: list, dest_path: str, pod_name_precise: str):
kubectl_create_dir_cmd = (f"kubectl"
f" exec -i {pod_name_precise} -n {data[0]} -- mkdir -p \"{dest_path}\"")
logging.info(f"Executing {kubectl_create_dir_cmd}")
os.system(kubectl_create_dir_cmd)


def copy_file_alt_kubectl(data: list, dest_path: str, local_path: Path, pod_name_precise: str, tries=4):
kubectl_alt_copy_cmd = (f"cat \"{local_path}\" |"
f" kubectl exec -i {pod_name_precise} -n {data[0]} -- tee \"{dest_path}\" > /dev/null")
logging.info(f"Executing {kubectl_alt_copy_cmd}")
exit_code = subprocess.call(kubectl_alt_copy_cmd, shell=True)
rich.print(f" [green]{local_path.name} ({local_path.stat().st_size / 1000} kB) successfully copied![/green]")
if exit_code != 0 and tries < 0:
rich.print("[red]Failed to copy.[/red]")
exit(1)
elif exit_code != 0 and tries > 0:
rich.print(f"Failed to copy will try again, try {tries}/4")
sleep(5)
copy_file_alt_kubectl(data, dest_path, local_path, pod_name_precise, tries - 1)

0 comments on commit fabb195

Please sign in to comment.