Skip to content

Commit

Permalink
Stabilize the current schema
Browse files Browse the repository at this point in the history
There's...a variety of warts in the current API schema.
In particular I really dislike `.image.image.image`.

But...but...changing it now would in practice be somewhat
difficult, and it's hard to say that just *that* tweak
would be really useful.

Let's just stabilize the existing spec as `v1` and commit
to maintaining it.

We've already added notes to ask callers to use `--format-version 1`
to specify what they want so we can compatibly add new things
in the future.

Speaking of, this also makes `--format-version=1` be the
same thing as `--format-version=0` so that all the versions
are just "1".

Closes: containers#518

Signed-off-by: Colin Walters <[email protected]>
  • Loading branch information
cgwalters committed Jul 31, 2024
1 parent 2fbda2a commit 5b5b572
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 21 deletions.
15 changes: 8 additions & 7 deletions docs/src/bootc-via-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,26 @@ At the current time, bootc is primarily intended to be
driven via a fork/exec model. The core CLI verbs
are stable and will not change.

## Using `bootc edit` and `bootc status --json --format-version=0`
## Using `bootc edit` and `bootc status --json`

While bootc does not depend on Kubernetes, it does currently
also offere a Kubernetes *style* API, especially oriented
towards the [spec and status and other conventions](https://kubernetes.io/docs/reference/using-api/api-concepts/).

In general, most use cases of driving bootc via API are probably
most easily done by forking off `bootc upgrade` when desired,
and viewing `bootc status --json --format-version=0`.
and viewing `bootc status --json --format-version=1`.

## JSON Schema

The current API is classified as `org.containers.bootc/v1alpha1` but
it will likely be officially stabilized mostly as is. However,
you should still request the current "v0" format via an explicit
`--format-version=0` as referenced above.
The current API `org.containers.bootc/v1` is stable.
In order to support the future introduction of a v2
or newer format, please change your code now to explicitly
request `--format-version=1` as referenced above. (Available
since bootc 0.1.15, `--format-version=0` in bootc 0.1.14).

There is a [JSON schema](https://json-schema.org/) generated from
the Rust source code available here: [host-v0.schema.json](host-v0.schema.json).
the Rust source code available here: [host-v1.schema.json](host-v1.schema.json).

A common way to use this is to run a code generator such as
[go-jsonschema](https://github.com/omissis/go-jsonschema) on the
Expand Down
24 changes: 24 additions & 0 deletions docs/src/host-v0.schema.json → docs/src/host-v1.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@
"pinned": {
"description": "Whether this entry will be subject to garbage collection",
"type": "boolean"
},
"store": {
"description": "The container storage backend",
"default": null,
"anyOf": [
{
"$ref": "#/definitions/Store"
},
{
"type": "null"
}
]
}
}
},
Expand Down Expand Up @@ -366,6 +378,18 @@
]
}
}
},
"Store": {
"description": "The container storage backend",
"oneOf": [
{
"description": "Use the ostree-container storage backend.",
"type": "string",
"enum": [
"ostreeContainer"
]
}
]
}
}
}
6 changes: 3 additions & 3 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ pub(crate) struct StatusOpts {
pub(crate) format: Option<OutputFormat>,

/// The desired format version. There is currently one supported
/// version, which is version `0`. Pass this option to explicitly
/// request it; it is possible that multiple versions will be
/// supported in the future.
/// version, which is exposed as both `0` and `1`. Pass this
/// option to explicitly request it; it is possible that another future
/// version 2 or newer will be supported in the future.
#[clap(long)]
pub(crate) format_version: Option<u32>,

Expand Down
1 change: 1 addition & 0 deletions lib/src/fixtures/spec-v1-null.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"apiVersion":"org.containers.bootc/v1","kind":"BootcHost","metadata":{"name":"host"},"spec":{"image":null,"bootOrder":"default"},"status":{"staged":null,"booted":null,"rollback":null,"rollbackQueued":false,"type":null}}
File renamed without changes.
File renamed without changes.
17 changes: 12 additions & 5 deletions lib/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};

use crate::k8sapitypes;

const API_VERSION: &str = "org.containers.bootc/v1alpha1";
const API_VERSION: &str = "org.containers.bootc/v1";
const KIND: &str = "BootcHost";
/// The default object name we use; there's only one.
pub(crate) const OBJECT_NAME: &str = "host";
Expand Down Expand Up @@ -226,8 +226,15 @@ mod tests {
use super::*;

#[test]
fn test_parse_spec_v0() {
const SPEC_FIXTURE: &str = include_str!("fixtures/spec.yaml");
fn test_parse_spec_v1_null() {
const SPEC_FIXTURE: &str = include_str!("fixtures/spec-v1-null.json");
let host: Host = serde_json::from_str(SPEC_FIXTURE).unwrap();
assert_eq!(host.resource.api_version, "org.containers.bootc/v1");
}

#[test]
fn test_parse_spec_v1a1_orig() {
const SPEC_FIXTURE: &str = include_str!("fixtures/spec-v1a1-orig.yaml");
let host: Host = serde_yaml::from_str(SPEC_FIXTURE).unwrap();
assert_eq!(
host.spec.image.as_ref().unwrap().image.as_str(),
Expand All @@ -236,8 +243,8 @@ mod tests {
}

#[test]
fn test_parse_spec_v1() {
const SPEC_FIXTURE: &str = include_str!("fixtures/spec-v1.yaml");
fn test_parse_spec_v1a1() {
const SPEC_FIXTURE: &str = include_str!("fixtures/spec-v1a1.yaml");
let host: Host = serde_yaml::from_str(SPEC_FIXTURE).unwrap();
assert_eq!(
host.spec.image.as_ref().unwrap().image.as_str(),
Expand Down
3 changes: 2 additions & 1 deletion lib/src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ pub(crate) fn get_status(
#[context("Status")]
pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> {
match opts.format_version.unwrap_or_default() {
0 => {}
// For historical reasons, both 0 and 1 mean "v1".
0 | 1 => {}
o => anyhow::bail!("Unsupported format version: {o}"),
};
let host = if !Utf8Path::new("/run/ostree-booted").try_exists()? {
Expand Down
6 changes: 3 additions & 3 deletions tests/booted/readonly/001-test-status.nu
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use tap.nu
tap begin "verify bootc status output formats"

let st = bootc status --json | from json
assert equal $st.apiVersion org.containers.bootc/v1alpha1
assert equal $st.apiVersion org.containers.bootc/v1
let st = bootc status --json --format-version=0 | from json
assert equal $st.apiVersion org.containers.bootc/v1alpha1
assert equal $st.apiVersion org.containers.bootc/v1
let st = bootc status --format=yaml | from yaml
assert equal $st.apiVersion org.containers.bootc/v1alpha1
assert equal $st.apiVersion org.containers.bootc/v1
tap ok
6 changes: 5 additions & 1 deletion tests/booted/readonly/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ def run(*args):
def test_bootc_status():
o = subprocess.check_output(["bootc", "status", "--json"])
st = json.loads(o)
assert st['apiVersion'] == 'org.containers.bootc/v1alpha1'
assert st['apiVersion'] == 'org.containers.bootc/v1'
for v in [0, 1]:
o = subprocess.check_output(["bootc", "status", "--json", f"--format-version={v}"])
st = json.loads(o)
assert st['apiVersion'] == 'org.containers.bootc/v1'

def test_bootc_status_invalid_version():
o = subprocess.call(["bootc", "status", "--json", "--format-version=42"])
Expand Down
2 changes: 1 addition & 1 deletion xtask/src/xtask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ fn update_generated(sh: &Shell) -> Result<()> {
.run()?;
}
let schema = cmd!(sh, "cargo run -q -- internals print-json-schema").read()?;
let target = "docs/src/host-v0.schema.json";
let target = "docs/src/host-v1.schema.json";
std::fs::write(target, &schema)?;
println!("Updated {target}");
Ok(())
Expand Down

0 comments on commit 5b5b572

Please sign in to comment.