The 'os_export' RPC is used to export an OS to a compressed tarball.
The path to this tarball will be given to the metadata daemon, which
will then be used to serve this package to the instances via the
instance communication mechanism.

Signed-off-by: Jose A. Lopes <[email protected]>
---
 lib/backend.py      | 37 +++++++++++++++++++++++++++++++++++++
 lib/rpc_defs.py     |  3 +++
 lib/server/noded.py |  8 ++++++++
 3 files changed, 48 insertions(+)

diff --git a/lib/backend.py b/lib/backend.py
index f8798bd..0b977ec 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -3882,6 +3882,43 @@ def ValidateOS(required, osname, checks, osparams, 
force_variant):
   return True
 
 
+def ExportOS(instance):
+  assert instance
+  assert instance.os
+
+  temp_dir = tempfile.mkdtemp()
+  inst_os = OSFromDisk(instance.os)
+
+  result = utils.RunCmd(["ln", "-s", inst_os.path,
+                         utils.PathJoin(temp_dir, "os")])
+  if result.failed:
+    _Fail("Failed to copy OS package '%s' to '%s': %s, output '%s'",
+          inst_os, temp_dir, result.fail_reason, result.output)
+
+  env = OSEnvironment(instance, inst_os)
+  with open(utils.PathJoin(temp_dir, "environment"), "w") as f:
+    for var in env:
+      f.write(var + "=" + env[var] + "\n")
+
+  (fd, os_package) = tempfile.mkstemp(suffix=".tgz")
+  os.close(fd)
+
+  result = utils.RunCmd(["tar", "--dereference", "-czv",
+                         "-f", os_package,
+                         "-C", temp_dir,
+                         "."])
+  if result.failed:
+    _Fail("Failed to create OS archive '%s': %s, output '%s'",
+          os_package, result.fail_reason, result.output)
+
+  result = utils.RunCmd(["rm", "-rf", temp_dir])
+  if result.failed:
+    _Fail("Failed to remove copy of OS package '%s' in '%s': %s, output '%s'",
+          inst_os, temp_dir, result.fail_reason, result.output)
+
+  return os_package
+
+
 def DemoteFromMC():
   """Demotes the current node from master candidate role.
 
diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py
index 0b83e1e..7eb53f0 100644
--- a/lib/rpc_defs.py
+++ b/lib/rpc_defs.py
@@ -466,6 +466,9 @@ _OS_CALLS = [
     ("params", None, None),
     ("force_variant", None, None),
     ], None, None, "Run a validation routine for a given OS"),
+  ("os_export", SINGLE, None, constants.RPC_TMO_FAST, [
+    ("instance", ED_INST_DICT, None),
+    ], None, None, "Export an OS for a given instance"),
   ]
 
 _EXTSTORAGE_CALLS = [
diff --git a/lib/server/noded.py b/lib/server/noded.py
index 702fdea..7c11b5a 100644
--- a/lib/server/noded.py
+++ b/lib/server/noded.py
@@ -994,6 +994,14 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     required, name, checks, params, force_variant = params
     return backend.ValidateOS(required, name, checks, params, force_variant)
 
+  @staticmethod
+  def perspective_os_export(params):
+    """Export an OS definition into an instance specific package.
+
+    """
+    instance = objects.Instance.FromDict(params[0])
+    return backend.ExportOS(instance)
+
   # extstorage -----------------------
 
   @staticmethod
-- 
1.9.1.423.g4596e3a

Reply via email to