cnabio / cnab-spec Goto Github PK
View Code? Open in Web Editor NEWCloud Native Application Bundle Specification
Home Page: https://cnab.io
License: Other
Cloud Native Application Bundle Specification
Home Page: https://cnab.io
License: Other
In some examples there is a uri
field on image
that appears (see examples in 101-bundle-json.md and 105-signing.md:
"images": [
{
"name": "image1",
"digest": "sha256:aaaa624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b",
"uri": "urn:image1uri",
"refs": [
{
"path": "image1path",
"field": "image.1.field"
}
],
}
]
However, this field appears neither in the spec, nor in the JSON schema.
Should it be removed from the examples, or added in the spec and schema?
We need to determine whether tooling and/or bundles are CNAB spec compliant. Let's determine the best path do doing that
The material necessary for reproducing the invocation image (Dockerfile and packer.json are two examples)
Do you expect this to also be provided for the other images as well? Do you expect the actual Dockerfile to be there or just a pointer to where it lives - like a URL to it in a github repo? I would expect some consistence here between all of the images.
Including the Dockerfile is an interesting choice... how much other info do you expect people to include to be able to fully rebuild the image? In many cases I would suspect that a Dockerfile is not sufficient so are you expecting them to recreate their entire build env in here? My gut is telling me to leave this out for now and add it later because this feels like it might be a rat-hole w/o clear boundaries. In the interest of not asking people to duplicate info, I'd suggest just a pointer to whatever info is needed to recreate it - if even that.
cnab/
re: /
- Do we assume non-windows file-system? :-) On the serious side, I haven't seen any mention of the platform in which this stuff will run, are you assuming Linux or Windows? Assuming multi-arch images? If a Linux dev built a cnab bundle, do you expect a Windows person to be able to cnab install
it? Some discussion of how you see the differences between various OSs, architectures, etc... might be good. Should also talk about what the prereqs are for running the cnab
tool.
Is the cnab bundle a zip file or tar ball?
This directory MUST have a subdirectory named app.
Why? Why not just put run
at the root of the cnab
dir? Even if you expect other top-level things, it sounds like run
is always the main entry point for everything so why bury it under app
? Or put it another way, what value does the app
dir provide for this executable? What would break, or be ambiguous, if it wasn't there?
This directory MUST NOT have any files or directories not explicitly named in the present document.
be careful. A v1.0 processor that sees v1.1 (optional) file, might halt process and error out based on this text. I think you'll find it easier to just say that unknown/extension files can be ignored then a v1.0 processor can still process a v1.1 bundle. If you're afraid of name conflicts then tell people to prefix their extension files with some domain (eg company) specific word - but they're added them at their own risk. If you want some gory info on a related topic see: https://github.com/cloudevents/spec/pull/353/files#diff-ed0940ecbc7be65c47b9414d516b3490R180
The OPTIONAL /cnab/build Directory
I'd add this dir to "The File System Layout" section FS map thingy.
However, the intention is to provide space for artifacts that are used during the assembly (or re-assembly) of the bundle, but are not part of the execution of a bundle action
This feels similar to asking for source code to live in a resulting docker image even though its not used at runtime. To save space, I doubt people will want their bundle (or images) to include anything but the bare minimum, so I'd keep the artifacts needed to build the images out of the images themselves.
Base Bundles
Should this be "Base Invocation Images"? Are we inheriting CNAB bundles or just invocation images? The body of the section focuses on images.
The most frequent way in which is occurs is...
s/which is/which this/
Most of the example bundles in the specification are missing the size property for invocation images, property that is required.
Update instances of:
The spec doesn't currently define how binary images are stored in a thick bundle. For example, It would be good to allow images to be stored as single files (e.g. .tar), for simplicity, or as a graph of layers, to optimise bundle size.
duffle seems to create an artifacts
directory and corresponding JSON file in a thick bundle, but the spec doesn't mention either of these or how they might be made available to the invocation image(s).
Perhaps the simplest sufficient spec would be to allow arbitrary files and directories inside an optional artifacts
directory in the root directory of a bundle and to mount the artifacts
directory at a defined location, such as /cnab/app/artifacts
, for invocation image(s) to access.
I am trying to understand where thick bundles will be useful. I have gone through the ycombinator thread as well as the spec, but it is not clear why anyone would really need this. Can someone provide some concrete examples. Thanks.
Parameters specify basic validation rules (e.g. min/max length, type). I'm wondering why not use JSON schema for a complete rule set which is standard, comprehensive and easy to implement?
Consider the following
{
"name": "notrelevant",
"version": "0.1.0",
"invocationImages": [
{
"image": "notrelevant"
}
],
"parameters": {
"something": {
"type": "string",
"destination": {
"env": "SOMETHING"
}
}
},
"credentials": {
"something": {
"env": "SOMETHING"
}
}
}
Note both the parameter and credential attempting to put a value in the same ENV. I think this should be invalid. It's not possible to pass both values as the same environment variable, but it's easy enough in the client to fail early.
I don't think I saw mention of this in the spec, and I think the behaviour should be specified rather than left to clients. Opening this for discussion to double check I've not missed something and the above reasoning is valid. Happy to submit a PR against the spec if so.
It feels a little like the bundle definition is repeated 3 times, first informally (in the section that starts with "A bundle.json is broken down into the following categories of information...") because it talks about it in generic terms - but also tries to be kind of prescriptive about its contents and only partially using RFC2119 keywords so I'm not sure how "spec-ish" this section is meant to be, then we see an example (which comes across as defining a spec by example), and finally again with a more formal definition (with the full RFC2119 keyword usage). I think it would read better if you either 1) put the RFC2119 section first and then showed a concrete example, or 2) showed the example with perhaps a short paragraph providing an overview (but not as prescriptive as it is today), and then got more formal with the RFC keyword section. I prefer 1)
And here is how a "thick" bundle looks...
Where does the actually image itself live? I kind of expected to see either a property in the json with the binary data of the image, or some mention of where the binary image resides on disk, in a tar file, etc...
The 'thick' bundle has a "platform" section with os and arch. I would have expected to see that being needed on the thin side too, or if not, then is this duplicating info that's part of the binary image itself? It seems it would be better to avoid the duplication and have the bundle processor get it directly from the image since it's error prone to duplicate it and can be complex, like in the case of a multi-arch image.
Fields that do not match this specification SHOULD cause failures
s/SHOULD/MUST/ otherwise the MUSTs above it aren't really MUSTs. And it should say how those failure manifest themselves - e.g. stop processing of the bundle?
Informational Metadata
This section should be more clear on the type of this metadata - e.g. "keywords" - is it a single string with comma separated words? an array of strings/words?
The appropriate invocation image is selected using the current driver.
The term "current driver" hasn't been used before (or I missed it), so I'm not sure what it means.
The bundle.json maps image metadata (name, origin, tag) to placeholders within the bundle.
Where are name, origin and tag defined?
Certain fields are required (e.g. version and image.description), but its not clear to me why - at least not yet. Are these required for a bundle processor to do its job? I'm guessing no, and if not I wouldn't make them required - it become noise/busywork for the author - and just asks them to fill it in with random (meaningless) garbage. This about the bare minimum a bundle needs to work, and only those things should be REQUIRED. You can make the other ones RECOMMENDED or SHOULDs.
Field Selectors
It's not clear to me what this section is for.
Parameters
I can't decide how I feel about this section. On the one hand I agree there will be a need to parameterize things, however, where does the normal install tool fit into this? For example, are you planning on this replacing Helm's templating stuff? Or to leverage it?
Credentials
How do you envision these being setup at runtime? By whom?
We need to implement a specification versioning scheme and release process
Images used by the application are referenced in the bundle and substituted by the runtime. At first I thought about substitution scenarios which are not defined in the spec like case sensitivity, substrings, wildcards, and more.. But then it occurred to me that it's better to just use regexp substitution, possibly with the familiar sed
format. For simple uses it won't impose too much burden on the user, but it will enable advanced uses with ease.
In the current CNAB spec, the parameters are defined inline with the bundle.json file. These parameters can either be exposed to the Invocation Image either as a environment variable or can be written to a file. However, for an application component which is depending on a defined configuration model in the form of a file (json/xml, etc.), the configuration values being exposed as environment variables, or being written to individual files might not be helpful. That would mean the particular component would have to be modified to fit the CNAB model.
In addition to the how parameters are currently defined, if a configuration element can be defined in the parameters file, with the relevant information on how to validate it (type, min, max, etc., similar to how the current parameters are implemented), and be looked up from a file source, it could be useful for some cases. After validation of the parameters in the source file, the same can be written to a target path (ex.: file path in the container when using docker driver), which can be read from the particular application component.
At a high level, this would require changes to the parameters section as shown below:
"parameters": {
"backend_port" : {
"type" : "int",
"defaultValue": 80,
"minValue": 10,
"maxValue": 10240,
"metadata": {
"description": "The port that the backend will listen on"
},
"source": {
"file": "~/dev/config/params.conf",
"lookup": "$.server.http.port[0]"
}
},
"destination": {
"file": "/home/config/params.conf"
}
}
Note the new source
block which tells where to find this parameter from the local file system, as well as the lookup
parameter which can be used to extract this particular parameter for validation purposes. In addition, a new destination
block is added to the top level of parameters, which include parameter file
, denoting the path where this config will be written to in the target application component, which can be then read at the runtime.
This model can be extended to support sources other than files as well.
Please do share your feedback on this approach, whether this would be useful/feasible.
There isn't must detail about credential handling. Shall we add a non-normative section?
In moving the spec, it appears that a large number of people have lost the ability to see this spec.
Can we please add a new group to this org, and add all the people that used to be able to read the spec?
There are some instances of json snippets not matching the spec. We need to make sure they reflect the defined spec
It is more a question than a suggestion.
IMO, claims seem more to be an implementation detail of Duffle. It can be used as a simple way to describe how a CNAB implementation can keep track of existing installations, as well as what data must be stored for future invocations as part of the runtime specification.
We have a mixture of formatting of RFC2119 keywords.
Let's settle on a standard:
Add standard DCO on commits wording to README
Before spotting #36 I wrote up a sample JSON Schema for bundle.json
, and jotted down a few ambiguities or questions I came across. See https://gist.github.com/garethr/5e45b35bff950ad3b62dd98fe592f3d3 for the schema.
schemaVersion
required?schemaVersion
is not required, what is the expected behaviour?uri
field for images, but the spec doesn't mention this field?invocationImages
be required?additionalProperties
be allowed that are not defined in the spec?string, int, boolean
for parameters.type
shortens int
but doesn't shorten boolean
Happy to submit PRs to address these once we have answers.
Install DCO Bot - https://github.com/integration/dco
When #62 was merged the changes weren't made to the schema, which still shows the image list: https://github.com/deislabs/cnab-spec/blob/master/schema/bundle.schema.json#L68
Why is 200 repositories not based on the OCI distribution spec?
OCI distribution was designed to handle different mime-types and since CNAB is a single bundled string of bytes this seems like a reasonable use case for it.
The upside is that every OCI/Docker registry could trivially add CNAB support without a ton of code changes.
As I make my way through the docs/spec, while I think I understand each piece being presented, what's missing for me is a high-level example to make the concepts concrete. For example, what do you think about providing a really simple (yet compelling) use-case that you walk through in an intro section of the 100 doc? Something that highlights the pain-point that's being addressed. Talk about how people do this today and show how much easier it'll be using the CNAB tool.
For example, one use-case that comes to mind is someone (who is NOT a kube, or containers, expert) wants to demo a kube app. Normally they might first need to download some CLI tools (kubectl, platform specific CLIs, etc...) and then create a cluster, install helm, use helm to install the app, and then finally they can hit the app in a browser. Perhaps show what this would look like using CNAB and how all of the complexities (and knowledge of each tool) is no longer needed - instead it's just cnab install ....
and bring up a browser.
You can then break apart the example and show how the CNAB bits map to each of the manual steps the demo runner would normally have done themselves. I think having this mapping would really help people see how this is all about automating, formalizing, what I think a lot of us already do today but instead of each of us creating some sh install script that we hope someone else can run when we try to share it, cnab ensures it. Do I have that right?
Over the course of development, we've realized some pretty severe limitations with the OpenPGP signing method we've been using. After investigation, the plan is to make these changes:
The names need to be namespaced. Without namespacing we can run into collision issues and confusion.
I'm assuming we know why namespacing is needed. I'm happy to go into detail if anyone needs it.
Before one or more proposed implementations come in as a pull request I thought it would be good to capture some requirements in an issue that can be referenced.
Namespacing should be 2 or more levels deep. For example, samsung.wordpress
and samsung.sds.wordpress
are both valid because some organizations have nested orgs
The same name should be valid if the package is pushed to more than one repository. This essentially means we cannot use a URL as the endpoint. This is needed, for example, to handle signed packages in mirrors or for organizations with multiple registries
#87 was merged last week.
@technosophos @bacongobbler @radu-matei this is unfortunately a mistake I think and wants reverting. The spec describes the case for destination not being set in bundle.json
, a default ENV value with a default name of $CNAB_P_<NAME>
:
https://github.com/deislabs/cnab-spec/blob/master/101-bundle-json.md#resolving-destinations
With the change in #87 the spec is currently inconsistent between the description of the destination
field and the resolution details and examples. Personally, I much prefer the original approach, it's less verbose for end users.
In the current form of the spec, it is unclear whether the parameter destination MUST set both environment variable and path - from the spec:
- destination: Indicates where (in the invocation image) the parameter is to be written (REQUIRED)
- env: The name of an environment variable
- path: The fully qualified path to a file that will be created
Should there be at least a clarification, stating that at least one of env
and path
must be set?
We should use Canonical JSON so that hashing is consistent across implementations.
Spec should address the case of conflicting parameter names, for example the image already has a similar env var at runtime. This is a rare edge case but better to define the behaviour in the spec rather than to leave for implementors to decide (or worse, to not decide).
The schema defines a field for license information, mentioning SPDX. https://github.com/deislabs/cnab-spec/blob/master/schema/bundle.schema.json#L55-L57
This isn't currently represented in the spec itself. Mentioning here as a reminder to update the spec. I think what's in the schema works.
Is there any chances to localize the specification for the Brazilian Portuguese Language ?
The spec says:
The schema version of the bundle, as a string with a v prefix. This schema is to be referenced as v1 or v1.0.0-WD
The the examples in the spec show:
"schemaVersion": "v1",
However, the JSON Schema states:
"description": "The version of the CNAB specification. This should always be the integer 1 for this schema version.",
I think the latter is wrong in this case, but which do we prefer?
As we're starting to have more clients that interact with bundles, it becomes inevitable that all clients will need to have multiple examples for bundles (and parts of bundles), and define corner cases to test - meaning the work is going to be replicated across repositories.
Would it make sense to have a common repository with example bundles and parts of bundles for clients to use as test data? (This way, we also try to make sure clients are up-to-date.)
images
and invocation images
objects have both an image reference and a digest field. However, an image reference can already contains a digest (for immutable image references), which is very confusing.
I suggest that we drop the digest
field, and make a comment on the image
field like:
image
MAY contain a muttable image reference ([registry/]repository[:tag]
) when the package is under developmentimage
MUST contain a digested (immutable) reference ([registry/]repository[:tag]@<digest>
) when the package is distributed (as a signed thin or thick CNAB, or trough an OCI registry).I've been going through the Spec and I was thinking about how a user can create a bundle that depends on multiple bundles. In the current Spec, we do have the ability to share bundles and thereby reuse them. But there is no concept of dependencies between them.
In a distributed system composed of many components running on heterogeneous environments, we would probably create multiple bundles for different components and deploy them. If I am to use a bundle that depends on other bundles, I need to separately pull each bundle and then install them separately.
However, when the number dependencies gets larger, finding all the dependencies and manually pulling them would be really hard for a user.
Do we have any plans to address this issue through the Spec?
In my opinion, we would have to introduce a Dependency Management Model for the bundles. By embedding this into the Spec at an early stage we can make sure that the bundles can be scaled well into larger distributed systems with many components.
Unfortunately, I do not have an exact proposal for this as of now. However, in my opinion we would have to consider the following if we are going to introduce this. (I am willing to contribute, if this seems like something you would like to add to the Spec)
WDYT?
The spec has had parameter validation since fd3d65a (#1), but the existing constraints are fairly limited and are maybe unique to this specification. Can we use JSON Schema's validation keywords (or a subset of those keywords) instead of rolling a custom validation format?
Currently in the bundle.json file spec, we define the format of an invocation image and also the format for other referenced images.
There are a number of differences between these that we should reconcile before we get to far along.
Invocation Image:
Optional fields:
For referenced images we have:
image
field from invocation image)I think that we should reconcile onto both having:
We for sure need an agreed upon type
of some sort. In the context of duffle, this is important for the invocation image so we select the appropriate driver, but also is important for validation of digest. The calculation of whatever hash is included in the digest will depend upon the type of image being operated against. The existing imageType
field on the invocationImage definition conveys enough meaning to drive this sort of behavior. In duffle, we want to validate digests of images in the image list as well, so it would be beneficial to have common definitions.
Clarify the target tool classes
for the spec. I think introducing the reader to these concepts frames the way in which they are considered. It may also lead to splitting up the spec into smaller specs in future.
Target tooling includes:
As they are currently defined, the bundle informational metadata does not specify a required status.
This issue keeps track of adding that status.
Docker images and Dockerfiles are used interchangeably in some cases. Let's use the OCI images specifically and rename as appropriate when it comes to Dockerfiles and image building.
Per a change from @simonferquel in cnabio/duffle#298, we need to add support for files
into the spec.
This is just a way to inject files from the local filesystem into the invocation image, and is part of effort here: cnabio/duffle#294
// Bundle is a CNAB metadata document
type Bundle struct {
Name string `json:"name" toml:"name"`
Version string `json:"version" toml:"version"`
Description string `json:"description" toml:"description"`
Keywords []string `json:"keywords" toml:"keywords"`
Maintainers []Maintainer `json:"maintainers" toml:"maintainers"`
InvocationImages []InvocationImage `json:"invocationImages" toml:"invocationImages"`
Images []Image `json:"images" toml:"images"`
Parameters map[string]ParameterDefinition `json:"parameters" toml:"parameters"`
Credentials map[string]CredentialLocation `json:"credentials" toml:"credentials"`
Files map[string]FileLocation `json:"files" toml:"files"`
}
Open to discussion: Should we make this behave more like a credential or parameter?
Document wording nomenclature used in spec.
in 100-CNAB, there's this line:
Finally, this document describes a format for invocation images...
Does "this document" refer to the current md file (100-CNAB) or does it mean the bundle? I'm guessing it should be "Finally, the bundle describes...." but I'm not 100% sure so I didn't open a PR
As I understand, a claim result.message
is the entire stdout of the invocation image (BTW, this should be written more clearly).
This design has a few issues:
/dev/null
which is cumbersome and error prone.I suggest to leave stdout to be (runtime developers may offer a method to retrieve it), and have developer craft the result message in a designated variable or file.
Additionally, I think it's useful to include the exit code as a field in the result, as it's already mandated by the spec.
Today Duffle's Docker Driver always mount /var/run/docker.sock in the invocation image. This provides a very easy way to do CNAB composition (CNABs invoking other CNABs) at the cost of exposing the whole engine API to the invocation image, without explicit consent (and of not being able to run Windows based invocation images).
In the case of Docker Enterprise, it is not even possible to do so for most users (for security reasons, mounting host files in a container in Docker EE requires very high privileges).
Also, in the Docker Enterprise case, RBAC rules are entirely bypassed when you manage to mount the docker socket inside a container, wich is something we clearly don't want.
So we need to fix this, and specify in the cnab-runtime spec, how a docker-driver will expose a docker daemon to the invocation image to achieve composition.
I suggest the following rule:
Additionally, should'net we add a field in bundle metadata to explicitly request for access to the Docker engine ? Maybe by introducing Driver specific options in Invocation Images ?
Ping @technosophos @garethr (as for now, it is only a braindump and I think it requires a few feedback iterations before writing a PR)
Starting a discussion about the question/TODO on 104-claims -
TODO: What is the best timestamp format to use? Does JSON have a preference?
I know you might have thought about it already but I could not find a Github issue with this so just thinking out loud -- How about using ISO-8601 formatted timestamp?
Should we remove support for CNAB_P_<param name>
?
Early CNAB did not allow custom parameter paths or env vars, and instead automatically injected parameters according the the formula CNAB_P_<PARAM NAMe>
(e.g. CNAB_P_PORT
)
Later, we added support for destination
, which allows setting the desired destination.
Is it time to remove the CNAB_P_
style parameters, or should we leave them?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.