Skip to content

Commit bde0a69

Browse files
committed
Implement creation of OCI images
1 parent 1105c92 commit bde0a69

File tree

1 file changed

+93
-1
lines changed

1 file changed

+93
-1
lines changed

mkosi/__init__.py

+93-1
Original file line numberDiff line numberDiff line change
@@ -3261,7 +3261,99 @@ def make_disk(
32613261

32623262

32633263
def make_oci(context: Context, root_layer: Path, dst: Path) -> None:
3264-
raise NotImplementedError
3264+
ca_store = dst / "blobs" / "sha256"
3265+
ca_store.mkdir(parents=True)
3266+
3267+
layer_diff_digest = hash_file(root_layer)
3268+
maybe_compress(
3269+
context,
3270+
context.config.compress_output,
3271+
context.staging / "rootfs.layer",
3272+
# Pass explicit destination to suppress adding an extension
3273+
context.staging / "rootfs.layer",
3274+
)
3275+
layer_digest = hash_file(root_layer)
3276+
root_layer.rename(ca_store / layer_digest)
3277+
3278+
creation_time = (
3279+
datetime.datetime.fromtimestamp(context.config.source_date_epoch, tz=datetime.timezone.utc)
3280+
if context.config.source_date_epoch
3281+
else datetime.datetime.now(tz=datetime.timezone.utc)
3282+
).isoformat()
3283+
3284+
oci_config = {
3285+
"created": creation_time,
3286+
"architecture": context.config.architecture.to_oci(),
3287+
# Name of the operating system which the image is built to run on as defined by
3288+
# https://github.com/opencontainers/image-spec/blob/v1.0.2/config.md#properties.
3289+
"os": "linux",
3290+
"rootfs": {
3291+
"type": "layers",
3292+
"diff_ids": [f"sha256:{layer_diff_digest}"],
3293+
},
3294+
"config": {
3295+
"Cmd": [
3296+
"/sbin/init",
3297+
*context.config.kernel_command_line,
3298+
*context.config.kernel_command_line_extra,
3299+
],
3300+
},
3301+
"history": [
3302+
{
3303+
"created": creation_time,
3304+
"comment": "Created by mkosi",
3305+
},
3306+
],
3307+
}
3308+
oci_config_blob = json.dumps(oci_config)
3309+
oci_config_digest = hashlib.sha256(oci_config_blob.encode()).hexdigest()
3310+
(ca_store / oci_config_digest).write_text(oci_config_blob)
3311+
3312+
layer_suffix = context.config.compress_output.oci_media_type_suffix()
3313+
oci_manifest = {
3314+
"schemaVersion": 2,
3315+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
3316+
"config": {
3317+
"mediaType": "application/vnd.oci.image.config.v1+json",
3318+
"digest": f"sha256:{oci_config_digest}",
3319+
"size": (ca_store / oci_config_digest).stat().st_size,
3320+
},
3321+
"layers": [
3322+
{
3323+
"mediaType": f"application/vnd.oci.image.layer.v1.tar{layer_suffix}",
3324+
"digest": f"sha256:{layer_digest}",
3325+
"size": (ca_store / layer_digest).stat().st_size,
3326+
}
3327+
],
3328+
"annotations": {
3329+
"io.systemd.mkosi.version": __version__,
3330+
**({
3331+
"org.opencontainers.image.version": context.config.image_version,
3332+
} if context.config.image_version else {}),
3333+
}
3334+
}
3335+
oci_manifest_blob = json.dumps(oci_manifest)
3336+
oci_manifest_digest = hashlib.sha256(oci_manifest_blob.encode()).hexdigest()
3337+
(ca_store / oci_manifest_digest).write_text(oci_manifest_blob)
3338+
3339+
with (dst / "index.json").open("w") as f:
3340+
json.dump(
3341+
{
3342+
"schemaVersion": 2,
3343+
"mediaType": "application/vnd.oci.image.index.v1+json",
3344+
"manifests": [
3345+
{
3346+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
3347+
"digest": f"sha256:{oci_manifest_digest}",
3348+
"size": (ca_store / oci_manifest_digest).stat().st_size,
3349+
}
3350+
],
3351+
},
3352+
f,
3353+
)
3354+
3355+
with (dst / "oci-layout").open("w") as f:
3356+
json.dump({"imageLayoutVersion": "1.0.0"}, f)
32653357

32663358

32673359
def make_esp(context: Context, uki: Path) -> list[Partition]:

0 commit comments

Comments
 (0)