Blame stages/org.osbuild.copy

Packit Service 863627
#!/usr/bin/python3
Packit Service 863627
"""
Packit Service 863627
Copy files from a source to the tree
Packit Service 863627
Packit Service 863627
Copies files obtained via a `source` to the tree. Multiple files or
Packit Service 863627
directories can be copied by specifying multiple entries in `paths`.
Packit Service 863627
If no paths are specified the whole contents of `source` is copied.
Packit Service 863627
The source and the target path for each individual path entry might
Packit Service 863627
optionally be specified via `from` and `to`, respectively; if no
Packit Service 863627
path is given for any of the two, the root `/` is assumed.
Packit Service 863627
Packit Service 863627
Supported sources are currently:
Packit Service 863627
Packit Service 863627
 o `archive`: Fetch an archive via the org.osbuild.files source and
Packit Service 863627
   extract it to a temporary directory. Currently only tar archives
Packit Service 863627
   are supported.
Packit Service 863627
Packit Service 863627
"""
Packit Service 863627
Packit Service 863627
Packit Service 863627
import json
Packit Service 863627
import os
Packit Service 863627
import sys
Packit Service 863627
import subprocess
Packit Service 863627
import tempfile
Packit Service 863627
Packit Service 863627
import osbuild.sources
Packit Service 863627
Packit Service 863627
Packit Service 863627
SCHEMA = """
Packit Service 863627
"additionalProperties": false,
Packit Service 863627
"definitions": {
Packit Service 863627
  "source-archive": {
Packit Service 863627
    "description": "Fetch an via org.osbuild.files and extract it",
Packit Service 863627
    "type": "object",
Packit Service 863627
    "required": ["type", "checksum"],
Packit Service 863627
    "additionalProperties": false,
Packit Service 863627
    "properties": {
Packit Service 863627
      "type": {
Packit Service 863627
        "type": "string",
Packit Service 863627
         "description": "The type of the source, here 'archive'",
Packit Service 863627
         "enum": ["archive"]
Packit Service 863627
      },
Packit Service 863627
      "checksum": {
Packit Service 863627
        "type": "string",
Packit Service 863627
        "description": "The checksum of the archive to fetch"
Packit Service 863627
      },
Packit Service 863627
      "strip-components": {
Packit Service 863627
        "type": "number",
Packit Service 863627
        "description": "Strip 'N' leading components from file names on extraction",
Packit Service 863627
        "default": 1
Packit Service 863627
      }
Packit Service 863627
    }
Packit Service 863627
  }
Packit Service 863627
},
Packit Service 863627
"properties": {
Packit Service 863627
  "source": {
Packit Service 863627
    "oneOf": [{ "$ref": "#/definitions/source-archive" }]
Packit Service 863627
  },
Packit Service 863627
  "paths": {
Packit Service 863627
    "description": "Array of items to copy",
Packit Service 863627
    "type": "array",
Packit Service 863627
    "items": {
Packit Service 863627
      "type": "object",
Packit Service 863627
      "additionalProperties": false,
Packit Service 863627
      "properties": {
Packit Service 863627
        "from": {
Packit Service 863627
          "type": "string",
Packit Service 863627
          "description": "The source path",
Packit Service 863627
          "default": "/"
Packit Service 863627
        },
Packit Service 863627
        "to": {
Packit Service 863627
          "type": "string",
Packit Service 863627
          "description": "The destination path",
Packit Service 863627
          "default": "/"
Packit Service 863627
        }
Packit Service 863627
      }
Packit Service 863627
    }
Packit Service 863627
  }
Packit Service 863627
}
Packit Service 863627
"""
Packit Service 863627
Packit Service 863627
Packit Service 863627
def get_archive(options, srcdir, workdir):
Packit Service 863627
    checksum = options["checksum"]
Packit Service 863627
    strip = options.get("strip-components", 1)
Packit Service 863627
    source_path = os.path.join(srcdir, "org.osbuild.files")
Packit Service 863627
Packit Service 863627
    target = os.path.join(workdir, checksum)
Packit Service 863627
    os.makedirs(target)
Packit Service 863627
Packit Service 863627
    # actually fetch the archive
Packit Service 863627
    res = osbuild.sources.get("org.osbuild.files", [checksum])
Packit Service 863627
Packit Service 863627
    tar = [
Packit Service 863627
        "tar",
Packit Service 863627
        "--strip-components=" + str(strip),
Packit Service 863627
        "-x",
Packit Service 863627
        "-C", target,
Packit Service 863627
        "-f", os.path.join(source_path, checksum)
Packit Service 863627
    ]
Packit Service 863627
Packit Service 863627
    subprocess.run(tar, check=True)
Packit Service 863627
Packit Service 863627
    return target, res
Packit Service 863627
Packit Service 863627
Packit Service 863627
def main(tree, srcdir, options, workdir):
Packit Service 863627
    source_options = options["source"]
Packit Service 863627
    source_type = source_options["type"]
Packit Service 863627
    paths = options.get("paths", [{}])
Packit Service 863627
Packit Service 863627
    if source_type == "archive":
Packit Service 863627
        source = get_archive
Packit Service 863627
    else:
Packit Service 863627
        raise ValueError(f"Unsupported source: {source_type}")
Packit Service 863627
Packit Service 863627
    # Fetch the requested data via the selected source
Packit Service 863627
    source_path, _ = source(source_options, srcdir, workdir)
Packit Service 863627
Packit Service 863627
    for path in paths:
Packit Service 863627
        src = path.get("from", "/")
Packit Service 863627
        dst = path.get("to", "/")
Packit Service 863627
Packit Service 863627
        subprocess.run(["cp", "--reflink=auto", "-a",
Packit Service 863627
                        f"{source_path}{src}",
Packit Service 863627
                        f"{tree}{dst}"],
Packit Service 863627
                       check=True)
Packit Service 863627
Packit Service 863627
Packit Service 863627
if __name__ == '__main__':
Packit Service 863627
    stage_args = json.load(sys.stdin)
Packit Service 863627
Packit Service 863627
    with tempfile.TemporaryDirectory(dir="/var/tmp") as _workdir:
Packit Service 863627
        r = main(stage_args["tree"],
Packit Service 863627
                 stage_args["sources"],
Packit Service 863627
                 stage_args["options"],
Packit Service 863627
                 _workdir)
Packit Service 863627
Packit Service 863627
        sys.exit(r)