def extract_last_layer()

in contrib/extract_last_layer.py [0:0]


def extract_last_layer(tar_path, layer_path, diffid_path):
  """Extracts the last layer from a docker image from an image tarball

  Args:
    tar_path: str path to the tarball
    layer_path: str path for the output layer
    diffid_path: str path for the layer diff ID


  Returns:
    str the diff ID of the layer

  """
  tar = tarfile.open(tar_path, mode="r")

  decoder = JSONDecoder()
  try:
    # Extracts it as a file object (not to the disk)
    manifest = tar.extractfile("manifest.json").read().decode("utf-8")
  except Exception as e:
    print((
        "Unable to extract manifest.json, make sure {} "
        "is a valid docker image.\n").format(tar_path),
          e,
          file=sys.stderr)
    exit(1)

  # Get the manifest dictionary from JSON
  manifest = decoder.decode(manifest)[0]

  # Get the last layer tar path
  layers = manifest["Layers"]

  last_layer_path = layers[-1]

  layer_id = last_layer_path.split("/")[0]

  # Hash the layer as we extract it
  diff_id = hashlib.sha256()

  try:
    # Extract the layer from the image to the output path
    last_layer = tar.extractfile(last_layer_path)
    with open(layer_path, "wb") as f:
      # Extract in blocks, to avoid loading the entire layer in memory
      while True:
        buf = last_layer.read(4096)
        if buf:
          diff_id.update(buf)
          f.write(buf)
        else:
          break
  except Exception as e:
    print((
        "Unable to extract last layer {} to {}, make sure {} "
        "is a valid docker image and that the layer path is writable\n").format(layer_id, layer_path, tar_path),
          e,
          file=sys.stderr)
    exit(1)

  # Output the diff ID hash
  diff_id_digest = diff_id.hexdigest()
  try:
    with open(diffid_path, "w") as f:
      f.write(diff_id_digest)
  except Exception as e:
    print("Unable to write layer Diff ID {} to {}, make sure the path is writeable\n".format(diff_id_digest, diffid_path), e, file=sys.stderr)
    exit(1)

  return layer_id