Skip to content

Commit 06755c2

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

File tree

1 file changed

+95
-1
lines changed

1 file changed

+95
-1
lines changed

mkosi/__init__.py

+95-1
Original file line numberDiff line numberDiff line change
@@ -3261,7 +3261,101 @@ 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(
3280+
context.config.source_date_epoch, tz=datetime.timezone.utc
3281+
)
3282+
if context.config.source_date_epoch
3283+
else datetime.datetime.now(tz=datetime.timezone.utc)
3284+
).isoformat()
3285+
3286+
oci_config = {
3287+
"created": creation_time,
3288+
"architecture": context.config.architecture.to_oci(),
3289+
# Name of the operating system which the image is built to run on as defined by
3290+
# https://github.com/opencontainers/image-spec/blob/v1.0.2/config.md#properties.
3291+
"os": "linux",
3292+
"rootfs": {
3293+
"type": "layers",
3294+
"diff_ids": [f"sha256:{layer_diff_digest}"],
3295+
},
3296+
"config": {
3297+
"Cmd": [
3298+
"/sbin/init",
3299+
*context.config.kernel_command_line,
3300+
*context.config.kernel_command_line_extra,
3301+
],
3302+
},
3303+
"history": [
3304+
{
3305+
"created": creation_time,
3306+
"comment": "Created by mkosi",
3307+
},
3308+
],
3309+
}
3310+
oci_config_blob = json.dumps(oci_config)
3311+
oci_config_digest = hashlib.sha256(oci_config_blob.encode()).hexdigest()
3312+
(ca_store / oci_config_digest).write_text(oci_config_blob)
3313+
3314+
layer_suffix = context.config.compress_output.oci_media_type_suffix()
3315+
oci_manifest = {
3316+
"schemaVersion": 2,
3317+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
3318+
"config": {
3319+
"mediaType": "application/vnd.oci.image.config.v1+json",
3320+
"digest": f"sha256:{oci_config_digest}",
3321+
"size": (ca_store / oci_config_digest).stat().st_size,
3322+
},
3323+
"layers": [
3324+
{
3325+
"mediaType": f"application/vnd.oci.image.layer.v1.tar{layer_suffix}",
3326+
"digest": f"sha256:{layer_digest}",
3327+
"size": (ca_store / layer_digest).stat().st_size,
3328+
}
3329+
],
3330+
"annotations": {
3331+
"io.systemd.mkosi.version": __version__,
3332+
**({
3333+
"org.opencontainers.image.version": context.config.image_version,
3334+
} if context.config.image_version else {}),
3335+
}
3336+
}
3337+
oci_manifest_blob = json.dumps(oci_manifest)
3338+
oci_manifest_digest = hashlib.sha256(oci_manifest_blob.encode()).hexdigest()
3339+
(ca_store / oci_manifest_digest).write_text(oci_manifest_blob)
3340+
3341+
with (dst / "index.json").open("w") as f:
3342+
json.dump(
3343+
{
3344+
"schemaVersion": 2,
3345+
"mediaType": "application/vnd.oci.image.index.v1+json",
3346+
"manifests": [
3347+
{
3348+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
3349+
"digest": f"sha256:{oci_manifest_digest}",
3350+
"size": (ca_store / oci_manifest_digest).stat().st_size,
3351+
}
3352+
],
3353+
},
3354+
f,
3355+
)
3356+
3357+
with (dst / "oci-layout").open("w") as f:
3358+
json.dump({"imageLayoutVersion": "1.0.0"}, f)
32653359

32663360

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

0 commit comments

Comments
 (0)