Revision 47f8a2d2 lib/backend.py

b/lib/backend.py
2016 2016
          disk.unique_id, disk.dev_type)
2017 2017

  
2018 2018

  
2019
def ExportSnapshot(disk, dest_node, instance, cluster_name, idx, debug):
2020
  """Export a block device snapshot to a remote node.
2021

  
2022
  @type disk: L{objects.Disk}
2023
  @param disk: the description of the disk to export
2024
  @type dest_node: str
2025
  @param dest_node: the destination node to export to
2026
  @type instance: L{objects.Instance}
2027
  @param instance: the instance object to whom the disk belongs
2028
  @type cluster_name: str
2029
  @param cluster_name: the cluster name, needed for SSH hostalias
2030
  @type idx: int
2031
  @param idx: the index of the disk in the instance's disk list,
2032
      used to export to the OS scripts environment
2033
  @type debug: integer
2034
  @param debug: debug level, passed to the OS scripts
2035
  @rtype: None
2036

  
2037
  """
2038
  inst_os = OSFromDisk(instance.os)
2039
  export_env = OSEnvironment(instance, inst_os, debug)
2040

  
2041
  export_script = inst_os.export_script
2042

  
2043
  logfile = _InstanceLogName("export", inst_os.name, instance.name)
2044
  if not os.path.exists(constants.LOG_OS_DIR):
2045
    os.mkdir(constants.LOG_OS_DIR, 0750)
2046

  
2047
  real_disk = _OpenRealBD(disk)
2048

  
2049
  export_env['EXPORT_DEVICE'] = real_disk.dev_path
2050
  export_env['EXPORT_INDEX'] = str(idx)
2051

  
2052
  destdir = utils.PathJoin(constants.EXPORT_DIR, instance.name + ".new")
2053
  destfile = disk.physical_id[1]
2054

  
2055
  # the target command is built out of three individual commands,
2056
  # which are joined by pipes; we check each individual command for
2057
  # valid parameters
2058
  expcmd = utils.BuildShellCmd("set -e; set -o pipefail; cd %s; %s 2>%s",
2059
                               inst_os.path, export_script, logfile)
2060

  
2061
  comprcmd = "gzip"
2062

  
2063
  destcmd = utils.BuildShellCmd("mkdir -p %s && cat > %s",
2064
                                destdir, utils.PathJoin(destdir, destfile))
2065
  remotecmd = _GetSshRunner(cluster_name).BuildCmd(dest_node,
2066
                                                   constants.GANETI_RUNAS,
2067
                                                   destcmd)
2068

  
2069
  # all commands have been checked, so we're safe to combine them
2070
  command = '|'.join([expcmd, comprcmd, utils.ShellQuoteArgs(remotecmd)])
2071

  
2072
  result = utils.RunCmd(["bash", "-c", command], env=export_env)
2073

  
2074
  if result.failed:
2075
    _Fail("OS snapshot export command '%s' returned error: %s"
2076
          " output: %s", command, result.fail_reason, result.output)
2077

  
2078

  
2079 2019
def FinalizeExport(instance, snap_disks):
2080 2020
  """Write out the export configuration information.
2081 2021

  
......
2175 2115
  return config.Dumps()
2176 2116

  
2177 2117

  
2178
def ImportOSIntoInstance(instance, src_node, src_images, cluster_name, debug):
2179
  """Import an os image into an instance.
2180

  
2181
  @type instance: L{objects.Instance}
2182
  @param instance: instance to import the disks into
2183
  @type src_node: string
2184
  @param src_node: source node for the disk images
2185
  @type src_images: list of string
2186
  @param src_images: absolute paths of the disk images
2187
  @type debug: integer
2188
  @param debug: debug level, passed to the OS scripts
2189
  @rtype: list of boolean
2190
  @return: each boolean represent the success of importing the n-th disk
2191

  
2192
  """
2193
  inst_os = OSFromDisk(instance.os)
2194
  import_env = OSEnvironment(instance, inst_os, debug)
2195
  import_script = inst_os.import_script
2196

  
2197
  logfile = _InstanceLogName("import", instance.os, instance.name)
2198
  if not os.path.exists(constants.LOG_OS_DIR):
2199
    os.mkdir(constants.LOG_OS_DIR, 0750)
2200

  
2201
  comprcmd = "gunzip"
2202
  impcmd = utils.BuildShellCmd("(cd %s; %s >%s 2>&1)", inst_os.path,
2203
                               import_script, logfile)
2204

  
2205
  final_result = []
2206
  for idx, image in enumerate(src_images):
2207
    if image:
2208
      destcmd = utils.BuildShellCmd('cat %s', image)
2209
      remotecmd = _GetSshRunner(cluster_name).BuildCmd(src_node,
2210
                                                       constants.GANETI_RUNAS,
2211
                                                       destcmd)
2212
      command = '|'.join([utils.ShellQuoteArgs(remotecmd), comprcmd, impcmd])
2213
      import_env['IMPORT_DEVICE'] = import_env['DISK_%d_PATH' % idx]
2214
      import_env['IMPORT_INDEX'] = str(idx)
2215
      result = utils.RunCmd(command, env=import_env)
2216
      if result.failed:
2217
        logging.error("Disk import command '%s' returned error: %s"
2218
                      " output: %s", command, result.fail_reason,
2219
                      result.output)
2220
        final_result.append("error importing disk %d: %s, %s" %
2221
                            (idx, result.fail_reason, result.output[-100]))
2222

  
2223
  if final_result:
2224
    _Fail("; ".join(final_result), log=False)
2225

  
2226

  
2227 2118
def ListExports():
2228 2119
  """Return a list of exports currently available on this machine.
2229 2120

  

Also available in: Unified diff