···
[2]: https://github.com/moby/moby/blob/4fb59c20a4fb54f944fe170d0ff1d00eb4a24d6f/image/spec/v1.2.md#image-json-field-descriptions
···
invalid_paths = [i for i in paths if not i.startswith(store_dir)]
-
assert len(invalid_paths) == 0, \
-
f"Expecting absolute paths from {store_dir}, but got: {invalid_paths}"
# First, calculate the tarball checksum and the size.
extract_checksum = ExtractChecksum()
-
mtime, uid, gid, uname, gname
(checksum, size) = extract_checksum.extract()
path = f"{checksum}/layer.tar"
···
# Then actually stream the contents to the outer tarball.
read_fd, write_fd = os.pipe()
with open(read_fd, "rb") as read, open(write_fd, "wb") as write:
-
mtime, uid, gid, uname, gname
# Closing the write end of the fifo also closes the read end,
···
target_tar.addfile(tarinfo, f)
-
paths=[customisation_layer]
···
-
with open(sys.argv[1], "r") as f:
-
datetime.now(tz=timezone.utc)
-
if conf["created"] == "now"
-
else datetime.fromisoformat(conf["created"])
mtime = int(created.timestamp())
···
for num, store_layer in enumerate(conf["store_layers"], start=start):
-
print("Creating layer", num, "from paths:", store_layer,
-
info = add_layer_dir(tar, store_layer, store_dir,
-
mtime, uid, gid, uname, gname)
-
print("Creating layer", len(layers) + 1, "with customisation...",
-
add_customisation_layer(
-
conf["customisation_layer"],
print("Adding manifests...", file=sys.stderr)
···
-
"created": datetime.isoformat(created),
-
"comment": f"store paths: {layer.paths}"
···
"Config": image_json_path,
-
"RepoTags": [conf["repo_tag"]],
"Layers": [layer.path for layer in layers],
···
[2]: https://github.com/moby/moby/blob/4fb59c20a4fb54f944fe170d0ff1d00eb4a24d6f/image/spec/v1.2.md#image-json-field-descriptions
···
invalid_paths = [i for i in paths if not i.startswith(store_dir)]
+
len(invalid_paths) == 0
+
), f"Expecting absolute paths from {store_dir}, but got: {invalid_paths}"
# First, calculate the tarball checksum and the size.
extract_checksum = ExtractChecksum()
+
archive_paths_to(extract_checksum, paths, mtime, uid, gid, uname, gname)
(checksum, size) = extract_checksum.extract()
path = f"{checksum}/layer.tar"
···
# Then actually stream the contents to the outer tarball.
read_fd, write_fd = os.pipe()
with open(read_fd, "rb") as read, open(write_fd, "wb") as write:
+
archive_paths_to(write, paths, mtime, uid, gid, uname, gname)
# Closing the write end of the fifo also closes the read end,
···
target_tar.addfile(tarinfo, f)
+
size=None, checksum=checksum, path=path, paths=[customisation_layer]
···
+
arg_parser = argparse.ArgumentParser(
+
This script generates a Docker image from a set of store paths. Uses
+
Docker Image Specification v1.2 as reference [1].
+
[1]: https://github.com/moby/moby/blob/master/image/spec/v1.2.md
+
arg_parser.add_argument(
+
JSON file with the following properties and writes the
+
image as an uncompressed tarball to stdout:
+
* "architecture", "config", "os", "created", "repo_tag" correspond to
+
the fields with the same name on the image spec [2].
+
* "created" can be "now".
+
* "created" is also used as mtime for files added to the image.
+
* "uid", "gid", "uname", "gname" is the file ownership, for example,
+
* "store_layers" is a list of layers in ascending order, where each
+
layer is the list of store paths to include in that layer.
+
arg_parser.add_argument(
+
"--repo_tag", "-t", type=str,
+
help="Override the RepoTags from the configuration"
+
args = arg_parser.parse_args()
+
with open(args.conf, "r") as f:
+
datetime.now(tz=timezone.utc)
+
if conf["created"] == "now"
+
else datetime.fromisoformat(conf["created"])
mtime = int(created.timestamp())
···
for num, store_layer in enumerate(conf["store_layers"], start=start):
+
tar, store_layer, store_dir, mtime, uid, gid, uname, gname
+
"with customisation...",
+
add_customisation_layer(
+
tar, conf["customisation_layer"], mtime=mtime
print("Adding manifests...", file=sys.stderr)
···
+
"created": datetime.isoformat(created),
+
"comment": f"store paths: {layer.paths}",
···
"Config": image_json_path,
+
"RepoTags": [args.repo_tag or conf["repo_tag"]],
"Layers": [layer.path for layer in layers],