I need to copy a file from a pod to the host by using kubernetes python client. It would be something like kubectl cp pod:file file
.
I'm testing the code from: https://github.com/prafull01/Kubernetes-Utilities/blob/master/kubectl_cp_as_python_client.py.
Specifically this code:
command_copy = ['tar', 'cf', '-', source_path]
with TemporaryFile() as tar_buffer:
exec_stream = stream(self.coreClient.connect_get_namespaced_pod_exec, pod_name, name_space,
command=command_copy, stderr=True, stdin=True, stdout=True, tty=False,
_preload_content=False)
# Copy file to stream
try:
while exec_stream.is_open():
exec_stream.update(timeout=1)
if exec_stream.peek_stdout():
out = exec_stream.read_stdout()
tar_buffer.write(out.encode('utf-8'))
if exec_stream.peek_stderr():
logger.debug("STDERR: %s" % exec_stream.read_stderr())
exec_stream.close()
tar_buffer.flush()
tar_buffer.seek(0)
with tarfile.open(fileobj=tar_buffer, mode='r:') as tar:
member = tar.getmember(source_path)
tar.makefile(member, destination_path)
return True
except Exception as e:
raise manage_kubernetes_exception(e)
I'm using the oficial Kubernetes Python library version 10.0.1 stable with Python 3.6.8
But it is not working properly:
Is there any mistake in the code? Do you have any other way to do it by using kubernetes python client?
All the best.
Thanks.
I did it by using the following code:
def stream_copy_from_pod(self, pod_name, name_space, source_path, destination_path):
"""
Copy file from pod to the host.
:param pod_name: String. Pod name
:param name_space: String. Namespace
:param source_path: String. Pod destination file path
:param destination_path: Host destination file path
:return: bool
"""
command_copy = ['tar', 'cf', '-', source_path]
with TemporaryFile() as tar_buffer:
exec_stream = stream(self.coreClient.connect_get_namespaced_pod_exec, pod_name, name_space,
command=command_copy, stderr=True, stdin=True, stdout=True, tty=False,
_preload_content=False)
# Copy file to stream
try:
reader = WSFileManager(exec_stream)
while True:
out, err, closed = reader.read_bytes()
if out:
tar_buffer.write(out)
elif err:
logger.debug("Error copying file {0}".format(err.decode("utf-8", "replace")))
if closed:
break
exec_stream.close()
tar_buffer.flush()
tar_buffer.seek(0)
with tarfile.open(fileobj=tar_buffer, mode='r:') as tar:
member = tar.getmember(source_path)
tar.makefile(member, destination_path)
return True
except Exception as e:
raise manage_kubernetes_exception(e)
Using this web socket file manager for read it.
class WSFileManager:
"""
WS wrapper to manage read and write bytes in K8s WSClient
"""
def __init__(self, ws_client):
"""
:param wsclient: Kubernetes WSClient
"""
self.ws_client = ws_client
def read_bytes(self, timeout=0):
"""
Read slice of bytes from stream
:param timeout: read timeout
:return: stdout, stderr and closed stream flag
"""
stdout_bytes = None
stderr_bytes = None
if self.ws_client.is_open():
if not self.ws_client.sock.connected:
self.ws_client._connected = False
else:
r, _, _ = select.select(
(self.ws_client.sock.sock, ), (), (), timeout)
if r:
op_code, frame = self.ws_client.sock.recv_data_frame(True)
if op_code == ABNF.OPCODE_CLOSE:
self.ws_client._connected = False
elif op_code == ABNF.OPCODE_BINARY or op_code == ABNF.OPCODE_TEXT:
data = frame.data
if len(data) > 1:
channel = data[0]
data = data[1:]
if data:
if channel == STDOUT_CHANNEL:
stdout_bytes = data
elif channel == STDERR_CHANNEL:
stderr_bytes = data
return stdout_bytes, stderr_bytes, not self.ws_client._connected
Do you have any other way to do it by using kubernetes python client?
If you just want one file from the Pod, then don't use tar
but rather /bin/cat
instead, with the added benefit that you can just write directly to the local file, without having to deal with the tar file format. The disadvantage to that approach is that you would be responsible for setting the permissions on the local file to match what you expected them to be, which is something that tar -xf
does for you. But if you're copying a remote tar file or zip file, that limitation wouldn't apply anyway, and may make the code a lot easier to reason about
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With