]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: create async function _write_remote_file to write files on remote host
authorMelissa <li.melissa.kun@gmail.com>
Tue, 20 Jul 2021 21:22:00 +0000 (17:22 -0400)
committerMelissa Li <li.melissa.kun@gmail.com>
Fri, 20 Aug 2021 18:27:45 +0000 (14:27 -0400)
_write_remote_file uses _check_execute_command in ssh.py which calls _execute_command which uses shlex quote. Thus, any commands with an int will need to be transformed into a str because shlex quote does not take int objects

Fixes: https://tracker.ceph.com/issues/44676
Signed-off-by: Melissa Li <li.melissa.kun@gmail.com>
src/pybind/mgr/cephadm/ssh.py

index 9ccfb3064a5c8d4728988cf015c20401ad2d5704..221d854c1dc8b259f0dc612077a47a24e22d1b11 100644 (file)
@@ -1,4 +1,5 @@
 import logging
+import os
 from contextlib import contextmanager
 from io import StringIO
 from shlex import quote
@@ -126,3 +127,29 @@ class SSHManager:
             raise OrchestratorError(msg)
         return out
 
+    async def _write_remote_file(self,
+                                 host: str,
+                                 path: str,
+                                 content: bytes,
+                                 mode: Optional[int] = None,
+                                 uid: Optional[int] = None,
+                                 gid: Optional[int] = None,
+                                 addr: Optional[str] = None,
+                                 **kwargs: Any,
+                                 ) -> None:
+        try:
+            dirname = os.path.dirname(path)
+            await self._check_execute_command(host, ['mkdir', '-p', dirname], addr=addr)
+            tmp_path = path + '.new'
+            await self._check_execute_command(host, ['touch', tmp_path], addr=addr)
+            if uid is not None and gid is not None and mode is not None:
+                # shlex quote takes str or byte object, not int
+                await self._check_execute_command(host, ['chown', '-R', str(uid) + ':' + str(gid), tmp_path], addr=addr)
+                await self._check_execute_command(host, ['chmod', oct(mode)[2:], tmp_path], addr=addr)
+            await self._check_execute_command(host, ['tee', '-', tmp_path], stdin=content, addr=addr)
+            await self._check_execute_command(host, ['mv', tmp_path, path], addr=addr)
+        except Exception as e:
+            msg = f"Unable to write {host}:{path}: {e}"
+            logger.exception(msg)
+            raise OrchestratorError(msg)
+