From 22724c6b33674117de627caa54adf9553610620f Mon Sep 17 00:00:00 2001 From: Lach Date: Tue, 8 Sep 2020 23:50:20 +0500 Subject: [PATCH 1/4] Implement OCI image spec Signed-off-by: Yaroslav Bolyukin --- Cargo.lock | 25 +++++++++ Cargo.toml | 3 + crates/oci-image-spec/Cargo.toml | 9 +++ crates/oci-image-spec/src/config.rs | 55 +++++++++++++++++++ .../oci-image-spec/src/content_descriptor.rs | 16 ++++++ crates/oci-image-spec/src/defs.rs | 8 +++ crates/oci-image-spec/src/image_index.rs | 37 +++++++++++++ crates/oci-image-spec/src/image_layout.rs | 8 +++ crates/oci-image-spec/src/image_manifest.rs | 12 ++++ crates/oci-image-spec/src/lib.rs | 6 ++ 10 files changed, 179 insertions(+) create mode 100644 crates/oci-image-spec/Cargo.toml create mode 100644 crates/oci-image-spec/src/config.rs create mode 100644 crates/oci-image-spec/src/content_descriptor.rs create mode 100644 crates/oci-image-spec/src/defs.rs create mode 100644 crates/oci-image-spec/src/image_index.rs create mode 100644 crates/oci-image-spec/src/image_layout.rs create mode 100644 crates/oci-image-spec/src/image_manifest.rs create mode 100644 crates/oci-image-spec/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index e7f95a7d..2085de1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -467,6 +467,14 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "oci-image-spec" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "os_str_bytes" version = "2.3.2" @@ -710,6 +718,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + [[package]] name = "serde" version = "1.0.115" @@ -730,6 +744,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "slab" version = "0.4.2" diff --git a/Cargo.toml b/Cargo.toml index 78ee9208..5bd65c73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,6 @@ tonic = "0.3.1" [build-dependencies] anyhow = "1.0.32" tonic-build = "0.3.1" + +[workspace] +members = ["crates/oci-image-spec"] diff --git a/crates/oci-image-spec/Cargo.toml b/crates/oci-image-spec/Cargo.toml new file mode 100644 index 00000000..ffdbf551 --- /dev/null +++ b/crates/oci-image-spec/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "oci-image-spec" +version = "0.1.0" +authors = ["Lach "] +edition = "2018" + +[dependencies] +serde = { version = "1.0.115", features = ["derive"] } +serde_json = "1.0.57" diff --git a/crates/oci-image-spec/src/config.rs b/crates/oci-image-spec/src/config.rs new file mode 100644 index 00000000..10a6fbdf --- /dev/null +++ b/crates/oci-image-spec/src/config.rs @@ -0,0 +1,55 @@ +//! OpenContainer Config Specification +use std::collections::HashMap; + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, PartialEq, Debug, Default, Deserialize, Serialize)] +pub struct Config { + #[serde(rename = "Cmd")] + pub cmd: Option, + #[serde(rename = "Entrypoint")] + pub entrypoint: Option, + #[serde(rename = "Env")] + pub env: Option>, + /// TODO: in original spec this is a map from string to object + /// serde_json::Value is the best type for this field which i can guess + #[serde(rename = "ExposedPorts")] + pub exposed_ports: Option>, + #[serde(rename = "Labels")] + pub labels: Option, + #[serde(rename = "StopSignal")] + pub stop_signal: Option, + #[serde(rename = "User")] + pub user: Option, + #[serde(rename = "Volumes")] + pub volumes: Option, + #[serde(rename = "WorkingDir")] + pub working_dir: Option, +} + +#[derive(Clone, PartialEq, Debug, Default, Deserialize, Serialize)] +pub struct ItemHistory { + pub author: Option, + pub comment: Option, + pub created: Option, + pub created_by: Option, + pub empty_layer: Option, +} + +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ItemHistoryRootfs { + pub diff_ids: Vec, + #[serde(rename = "type")] + pub item_type: String, +} + +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct RootConfig { + pub architecture: String, + pub author: Option, + pub config: Option, + pub created: Option, + pub history: Option>, + pub os: String, + pub rootfs: ItemHistoryRootfs, +} diff --git a/crates/oci-image-spec/src/content_descriptor.rs b/crates/oci-image-spec/src/content_descriptor.rs new file mode 100644 index 00000000..875fe69a --- /dev/null +++ b/crates/oci-image-spec/src/content_descriptor.rs @@ -0,0 +1,16 @@ +use crate::defs::{Annotations, Digest, MediaType, Url}; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ContentDescriptor { + pub annotations: Option, + /// the cryptographic checksum digest of the object, in the pattern ':' + pub digest: Digest, + /// the mediatype of the referenced object + #[serde(rename = "mediaType")] + pub media_type: MediaType, + /// the size in bytes of the referenced object + pub size: i64, + /// a list of urls from which this object may be downloaded + pub urls: Option>, +} diff --git a/crates/oci-image-spec/src/defs.rs b/crates/oci-image-spec/src/defs.rs new file mode 100644 index 00000000..6134b620 --- /dev/null +++ b/crates/oci-image-spec/src/defs.rs @@ -0,0 +1,8 @@ +use std::collections::HashMap; + +pub type Annotations = HashMap; +/// the cryptographic checksum digest of the object, in the pattern ':' +pub type Digest = String; +/// https://opencontainers.org/schema/image/descriptor/mediaType +pub type MediaType = String; +pub type Url = String; diff --git a/crates/oci-image-spec/src/image_index.rs b/crates/oci-image-spec/src/image_index.rs new file mode 100644 index 00000000..0cb0d87b --- /dev/null +++ b/crates/oci-image-spec/src/image_index.rs @@ -0,0 +1,37 @@ +use crate::defs::{Digest, MediaType, Url}; + +use super::defs::Annotations; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ImageIndexItemManifestsPlatform { + pub architecture: String, + pub os: String, + #[serde(rename = "os.features")] + pub os_features: Option>, + #[serde(rename = "os.version")] + pub os_version: Option, + pub variant: Option, +} +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ImageIndexItemManifests { + pub annotations: Option, + /// the cryptographic checksum digest of the object, in the pattern ':' + pub digest: Digest, + /// the mediatype of the referenced object + #[serde(rename = "mediaType")] + pub media_type: MediaType, + pub platform: Option, + /// the size in bytes of the referenced object + pub size: i64, + /// a list of urls from which this object may be downloaded + pub urls: Option>, +} +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ImageIndex { + pub annotations: Option, + pub manifests: Vec, + /// This field specifies the image index schema version as an integer + #[serde(rename = "schemaVersion")] + pub schema_version: i64, +} diff --git a/crates/oci-image-spec/src/image_layout.rs b/crates/oci-image-spec/src/image_layout.rs new file mode 100644 index 00000000..b20ee6e5 --- /dev/null +++ b/crates/oci-image-spec/src/image_layout.rs @@ -0,0 +1,8 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ImageLayout { + /// version of the OCI Image Layout (in the oci-layout file) + #[serde(rename = "imageLayoutVersion")] + pub image_layout_version: String, +} diff --git a/crates/oci-image-spec/src/image_manifest.rs b/crates/oci-image-spec/src/image_manifest.rs new file mode 100644 index 00000000..b5829595 --- /dev/null +++ b/crates/oci-image-spec/src/image_manifest.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +use crate::{content_descriptor::ContentDescriptor, defs::Annotations}; +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] +pub struct ImageManifest { + pub annotations: Option, + pub config: ContentDescriptor, + pub layers: Vec, + /// This field specifies the image manifest schema version as an integer + #[serde(rename = "schemaVersion")] + pub schema_version: i64, +} diff --git a/crates/oci-image-spec/src/lib.rs b/crates/oci-image-spec/src/lib.rs new file mode 100644 index 00000000..bf87c0d9 --- /dev/null +++ b/crates/oci-image-spec/src/lib.rs @@ -0,0 +1,6 @@ +pub mod config; +pub mod content_descriptor; +pub mod defs; +pub mod image_index; +pub mod image_layout; +pub mod image_manifest; From 3be2043f7344d358342b37bcabfce321fa5c6eef Mon Sep 17 00:00:00 2001 From: Lach Date: Wed, 9 Sep 2020 00:26:21 +0500 Subject: [PATCH 2/4] More concrete types in config Signed-off-by: Yaroslav Bolyukin --- crates/oci-image-spec/src/config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/oci-image-spec/src/config.rs b/crates/oci-image-spec/src/config.rs index 10a6fbdf..9dd013cb 100644 --- a/crates/oci-image-spec/src/config.rs +++ b/crates/oci-image-spec/src/config.rs @@ -6,9 +6,9 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, PartialEq, Debug, Default, Deserialize, Serialize)] pub struct Config { #[serde(rename = "Cmd")] - pub cmd: Option, + pub cmd: Option>, #[serde(rename = "Entrypoint")] - pub entrypoint: Option, + pub entrypoint: Option>, #[serde(rename = "Env")] pub env: Option>, /// TODO: in original spec this is a map from string to object @@ -16,13 +16,13 @@ pub struct Config { #[serde(rename = "ExposedPorts")] pub exposed_ports: Option>, #[serde(rename = "Labels")] - pub labels: Option, + pub labels: Option>, #[serde(rename = "StopSignal")] pub stop_signal: Option, #[serde(rename = "User")] pub user: Option, #[serde(rename = "Volumes")] - pub volumes: Option, + pub volumes: Option>, #[serde(rename = "WorkingDir")] pub working_dir: Option, } From 773754d865dac5136fc2d557a6a929efc821c5a7 Mon Sep 17 00:00:00 2001 From: Lach Date: Wed, 9 Sep 2020 00:27:14 +0500 Subject: [PATCH 3/4] Rename history types Signed-off-by: Yaroslav Bolyukin --- crates/oci-image-spec/src/config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/oci-image-spec/src/config.rs b/crates/oci-image-spec/src/config.rs index 9dd013cb..248221be 100644 --- a/crates/oci-image-spec/src/config.rs +++ b/crates/oci-image-spec/src/config.rs @@ -28,7 +28,7 @@ pub struct Config { } #[derive(Clone, PartialEq, Debug, Default, Deserialize, Serialize)] -pub struct ItemHistory { +pub struct History { pub author: Option, pub comment: Option, pub created: Option, @@ -37,7 +37,7 @@ pub struct ItemHistory { } #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] -pub struct ItemHistoryRootfs { +pub struct HistoryRootfs { pub diff_ids: Vec, #[serde(rename = "type")] pub item_type: String, @@ -49,7 +49,7 @@ pub struct RootConfig { pub author: Option, pub config: Option, pub created: Option, - pub history: Option>, + pub history: Option>, pub os: String, - pub rootfs: ItemHistoryRootfs, + pub rootfs: HistoryRootfs, } From 5d88c9d22dcb1fe472331b323b9e730dd674dbab Mon Sep 17 00:00:00 2001 From: Lach Date: Wed, 9 Sep 2020 00:28:25 +0500 Subject: [PATCH 4/4] Simplify image index naming Signed-off-by: Yaroslav Bolyukin --- crates/oci-image-spec/src/image_index.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/oci-image-spec/src/image_index.rs b/crates/oci-image-spec/src/image_index.rs index 0cb0d87b..bb86946b 100644 --- a/crates/oci-image-spec/src/image_index.rs +++ b/crates/oci-image-spec/src/image_index.rs @@ -1,10 +1,9 @@ -use crate::defs::{Digest, MediaType, Url}; - use super::defs::Annotations; +use crate::defs::{Digest, MediaType, Url}; use serde::{Deserialize, Serialize}; #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] -pub struct ImageIndexItemManifestsPlatform { +pub struct Platform { pub architecture: String, pub os: String, #[serde(rename = "os.features")] @@ -13,24 +12,26 @@ pub struct ImageIndexItemManifestsPlatform { pub os_version: Option, pub variant: Option, } + #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] -pub struct ImageIndexItemManifests { +pub struct Manifests { pub annotations: Option, /// the cryptographic checksum digest of the object, in the pattern ':' pub digest: Digest, /// the mediatype of the referenced object #[serde(rename = "mediaType")] pub media_type: MediaType, - pub platform: Option, + pub platform: Option, /// the size in bytes of the referenced object pub size: i64, /// a list of urls from which this object may be downloaded pub urls: Option>, } + #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] pub struct ImageIndex { pub annotations: Option, - pub manifests: Vec, + pub manifests: Vec, /// This field specifies the image index schema version as an integer #[serde(rename = "schemaVersion")] pub schema_version: i64,