]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: _write_remote_file helper
authorSage Weil <sage@newdream.net>
Tue, 20 Apr 2021 22:18:46 +0000 (18:18 -0400)
committerSage Weil <sage@newdream.net>
Thu, 22 Apr 2021 02:13:02 +0000 (22:13 -0400)
This is careful is ownership, mode, and fsyncs before renaming into
position.

Signed-off-by: Sage Weil <sage@newdream.net>
src/pybind/mgr/cephadm/remotes.py
src/pybind/mgr/cephadm/serve.py

index 0ad7006831d62eaaf358474547a2507008dd277d..e1ecf2dcbe93b2548e93e303e1f8286534f1fa20 100644 (file)
@@ -26,6 +26,25 @@ def choose_python():
     return None
 
 
+def write_file(path: str, content: bytes, mode: int, uid: int, gid: int,
+               mkdir_p: bool = True) -> Optional[str]:
+    try:
+        if mkdir_p:
+            dirname = os.path.dirname(path)
+            if not os.path.exists(dirname):
+                os.makedirs(dirname)
+        tmp_path = path + '.new'
+        with open(tmp_path, 'wb') as f:
+            os.fchown(f.fileno(), uid, gid)
+            os.fchmod(f.fileno(), mode)
+            f.write(content)
+            os.fsync(f.fileno())
+        os.rename(tmp_path, path)
+    except Exception as e:
+        return str(e)
+    return None
+
+
 if __name__ == '__channelexec__':
     for item in channel:  # type: ignore # noqa: F821
         channel.send(eval(item))  # type: ignore # noqa: F821
index 69fbaff40601b9800566a843bbce3ac0de3a0851..c1b9feca457bec6cbb10abd20888e448e0aa21f9 100644 (file)
@@ -1139,6 +1139,24 @@ class CephadmServe:
             self.log.warning(msg)
             raise OrchestratorError(msg)
 
+    def _write_remote_file(self,
+                           host: str,
+                           path: str,
+                           content: bytes,
+                           mode: int,
+                           uid: int,
+                           gid: int) -> None:
+        with self._remote_connection(host) as tpl:
+            conn, connr = tpl
+            try:
+                errmsg = connr.write_file(path, content, mode, uid, gid)
+                if errmsg is not None:
+                    raise OrchestratorError(errmsg)
+            except Exception as e:
+                msg = f"Unable to write {host}:{path}: {e}"
+                self.log.warning(msg)
+                raise OrchestratorError(msg)
+
     @contextmanager
     def _remote_connection(self,
                            host: str,