diff --git a/docs/getting-started.md b/GETTING_STARTED.md similarity index 100% rename from docs/getting-started.md rename to GETTING_STARTED.md diff --git a/docs/glossary.md b/GLOSSARY.md similarity index 100% rename from docs/glossary.md rename to GLOSSARY.md diff --git a/docs/implementation_guide.md b/IMPLEMENTATION_GUIDE.md similarity index 100% rename from docs/implementation_guide.md rename to IMPLEMENTATION_GUIDE.md diff --git a/README.md b/README.md index 4b41732..cd551de 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,10 @@ The Nulecule specification enables complex applications to be defined, packaged **[Glossary of terms](docs/glossary.md)** +## Specification + +An actively maintained page on the specifics of the specification can be found at [SPECIFICATION.md](SPECIFICATION.md). + ## Nulecule Specification Highlights * Application description and context maintained in a single container through extensible metadata @@ -36,90 +40,51 @@ The Nulecule specification enables complex applications to be defined, packaged ## Deployment User Experience -The Nulecule specification has been implemented in the [Atomic App reference implementation](https://github.com/projectatomic/atomicapp). Atomic App currently supports docker containers and kubernetes and docker orchestration providers. The [atomic command](https://github.com/projectatomic/atomic) is used to run the container that contains the Nulecule specification and the Atomic App implementation. - -This example is a single container application based on the centos/httpd image, but you can use your own. - -You may wish to run the Nulecule from an empty directory as it will copy the Nulecule files to the working directory for inspection every time it is run. - -### Option 1: Non-interactive defaults - -Run the image. It will automatically use kubernetes as the orchestration provider. This will become interactive and prompt for defaults if the Nulecule file doesn't provide defaults for all of the parameters. - -``` -[sudo] atomic run projectatomic/helloapache -``` - -### Option 2: Unattended - -1. Create the file `answers.conf` with these contents: - - This sets up the values for the two configurable parameters (image and hostport) and indicates that kubernetes should be the orchestration provider. - - [general] - provider = kubernetes - - [helloapache-app] - image = centos/httpd # optional: choose a different image - hostport = 80 # optional: choose a different port to expose -1. Run the application from the current working directory - - $ [sudo] atomic run projectatomic/helloapache - ... - helloapache +The Nulecule specification has been implemented in the [Atomic App reference implementation](https://github.com/projectatomic/atomicapp). Atomic App currently supports docker as well as container orchestrators such as Kubernetes, OpenShift and Marathon. The [atomic](https://github.com/projectatomic/atomic) or [atomicapp](https://github.com/projectatomic/atomicapp] command is used to run the container that contains the Nulecule specification. +## Getting started on Nulecule with Atomic App -1. As an additional experiment, remove the kubernetes pod and change the provider to 'docker' and re-run the application to see it get deployed on native docker. +Nulecule can use the Atomic App implementation which can be used either natively on your OS __or__ ran via the [atomic](https://github.com/projectatomic/atomic) command on [Fedora or CentOS Atomic hosts](https://www.projectatomic.io/download/). -### Option 3: Install and Run +__Detailed instructions on [getting started](https://github.com/projectatomic/atomicapp/blob/master/docs/start_guide.md) are available.__ Alternatively, use the [quick start guide](https://github.com/projectatomic/atomicapp/blob/master/docs/quick_start.md) to get a Nuleculized application running immediately. -You may want to download the application, review the configuration and parameters as specified in the Nulecule file, and edit the answerfile before running the application. - -1. Download the application files using `atomic install` - - [sudo] atomic install projectatomic/helloapache - -1. Rename `answers.conf.sample` - - mv answers.conf.sample answers.conf - -1. Edit `answers.conf`, review files if desired and then run - - $ [sudo] atomic run projectatomic/helloapache - ... - helloapache - -## Test -Any of these approaches should create a kubernetes pod or a running docker container. - -With a kubernetes pod, once its state is "Running" curl the minion it's running on. - -``` -$ kubectl get pod helloapache -POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS -helloapache 172.17.0.8 helloapache centos/httpd 10.3.9.216/ name=helloapache Running -$ curl 10.3.9.216 - -``` - -If you test the docker provider, once the container is running, curl the port on your localhost. +This example is a single container application based on the centos/httpd image, but you can use your own. +A quick example of this being used are launching the `projectatomic/helloapache` example: + +```bash +▶ sudo atomicapp run projectatomic/helloapache --destination helloapache +INFO :: Atomic App: 0.5.2 - Mode: Run +INFO :: Unpacking image projectatomic/helloapache to helloapache +INFO :: Skipping pulling docker image: projectatomic/helloapache +INFO :: Extracting Nulecule data from image projectatomic/helloapache to helloapache +INFO :: App exists locally and no update requested +INFO :: Using namespace default +INFO :: trying kubectl at /usr/bin/kubectl +INFO :: trying kubectl at /usr/local/bin/kubectl +INFO :: found kubectl at /usr/local/bin/kubectl +INFO :: Deploying to Kubernetes + +Your application resides in helloapache +Please use this directory for managing your application + +▶ kubectl get po +NAME READY STATUS RESTARTS AGE +helloapache 1/1 Running 0 6s +k8s-etcd-127.0.0.1 1/1 Running 0 20d +k8s-master-127.0.0.1 4/4 Running 0 23h +k8s-proxy-127.0.0.1 1/1 Running 0 23h ``` -$ curl localhost - -``` - -Additional examples are available in the [examples](examples/) directory. ## Developer User Experience -See the [Getting Started with Nulecule guide](docs/getting-started.md). +See the [Getting Started with Nulecule guide](GETTING_STARTED.md). ## Implementations -This is only a specification. Implementations may be written in any language. See [implementation guide](/docs/implementation_guide.md) for more details. +This is only a specification. Implementations may be written in any language. See [implementation guide](IMPLEMENTATION_GUIDE.md) for more details. -**Reference implementation** https://github.com/projectatomic/atomicapp +**Reference implementation:** https://github.com/projectatomic/atomicapp ## Examples / Library diff --git a/SPECIFICATION.md b/SPECIFICATION.md new file mode 100644 index 0000000..12ed45a --- /dev/null +++ b/SPECIFICATION.md @@ -0,0 +1,320 @@ +# Nulecule file + +A `Nulecule` file format can either be `json` or `yaml`. + +#### Version 0.0.2 + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](http://www.ietf.org/rfc/rfc2119.txt). + +The Container Application Specification is licensed under [GNU Free Documentation License Version 1.3, 3 November 2008](https://www.gnu.org/copyleft/fdl.html). + + +## Introduction + +The Container Application specification is a project to describe 'an Application' that is composed of a set of dependent Container Applications (containerapp). The Container Application specification defines a set of files required to describe such a containerapp. These files can then be used by other tools to deploy a containerapp. Developers may use other tools to generate most of the required containerapp files. Additional utilities can also take advantage of the resulting files, such as testing tools. + +### Versioning + +Within this specification we follow [the semantic versioning pattern](http://semver.org/spec/v2.0.0.html). + +## Revision History + +Version | Date | Notes +--- | --- | --- +0.0.2 | 2015-05-07 | close issue #35 the graph is now a list of named items +0.0.1-alpha | 2015-mm-dd | TBD +v1-alpha | 2015-04-10 | reversioned to 0.0.1-alpha + +## Specification + +### Format + +The files describing a containerapp in accordance with the Container Application Specification are represented using [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) or [JSON](http://json.org/). + +All field names in the specification are **case sensitive**. + +By convention, the containerapp definition file is named `Nulecule`. The Nulecule is the primary file defining the containerapp and it's relationship to dependencies. + +### Data types + +Common Name | `type` | `format` | Comments +----------- | --------- | ----------- | -------------- +integer | `integer` | `int32` | signed 64 bits +float | `number` | `float` | +string | `string` | | +byte | `string` | `byte` | +boolean | `boolean` | | +date | `string` | `date` | As defined by `full-date` - [RFC3339](http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14) +dateTime | `string` | `date-time` | As defined by `date-time` - [RFC3339](http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14) +password | `string` | `password` | Used to hint UIs the input needs to be obscured. +URL | `URL` | `URL` | As defined by `URL` - [RFC3986 Section 1.1.3](https://tools.ietf.org/html/rfc3986#section-1.1.3) + +### Nulecule file schema + +#### Container Application Object +This is the root object for the specification. + +Field Name | Type | Description +---------- | :-----------------: | ------------ +id | `string` | **Required.** The machine readable id of the Container Application. +specversion | `string` | **Required.** The semantic version string of the Container Application Specification used to describe the app. The value MUST be `"0.0.2"` (current version of the spec). +metadata | `Metadata Object` | **Optional** An object holding optional metadata related for the Container Application, this may include license information or human readable information. +graph | `Graph Object` | **Required.** A list of depending containerapps. Strings may either match a local sub directory or another containerapp-spec compliant containerapp image that can be pulled via docker. +requirements|`Requirements Object`| **Optional.** A list of requirements of this containerapp. + + +#### Metadata Object + +Metadata for the Container Application. + +##### Fields + +Field Name | Type | Description +---------------|:---------------:| ------------ +name | `string` | **Optional.** A human readable name of the containerapp. +appversion | `string` | **Optional.** The semantic version string of the Container Application. +description | `string` | **Optional.** A human readable description of the Container Application. This may contain information for the deployer of the containerapp. +license | `License Object`| **Optional.** The license information for the containerapp. +arbitrary_data | `string` | **Optional.** Arbitrary `key: value` pair(s) of metadata. May contain nested objects. + +##### Metadata Object Example + +```yaml +metadata: + name: myapp + appversion: 1.0.0 + description: description of myapp + foo: bar + othermetadata: + foo: bar + files: file://path/to/local/file +... +``` + +#### License Object + +License information for the Container Application. + +##### Fields + +Field Name | Type | Description +-----------|:--------:|--- +name | `string` | **Required.** The human readable license name used for the Container Application, no format imposed. +url | `string` | **Optional.** A URL to the license used for the API. MUST be in the format of a URL. + +##### License Object Example + +```yaml +license: + - name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html +``` + +#### Graph Object + +The graph is a list of items (containerapps) the Container Application depends on. + +##### Fields + +Field Name| Type | Description +----------|:-----------------:|------------- +name | `string` | **Required.** The name of the depending Container Application. +source | `docker://` | **Optional.** `docker://` source location of the Container Application, the source MUST be prefixed by `docker://`. If source is present, all other fields SHALL be ignored. +params | `Params Object` | **Optional.** A list of `Params Objects` that contain provider specific information. If params is present, source field SHALL be ignored. +artifacts | `Artifact Object` | **Optional.** A list of `Artifact Objects` that contain provider specific information. If artifacts is present, source field SHALL be ignored. + +##### Graph Item Object Example: + +```yaml +params: + - name: mariadb-centos7-atomicapp + source: docker://projectatomic/mariadb-centos7-atomicapp + ... +``` + +If no `artifacts` are specified, then an external Atomic App is pulled and installed from the `docker://` source. + +#### Parameters Object + +A list of Parameters the containerapp requires. Defaults may be set, otherwise user input is required. + +##### Fields + +Field Name | Type | Description +------------|:-----------------:|------------- +name | `string` | **Required.** The name of the parameter. +description | `string` | **Required.** A human readable description of the parameter. +default | `string` | **Optional.** An optional default value for the parameter. + +##### Parameters Object Example: + +```yaml +params: + - name: image + description: wordpress image + default: wordpress + ... +``` + +#### Requirements Object + +The list of requirements of the Container Application. + +Field Name | Type | Description +---------------- | :-----------------------: | ------------ +persistentVolume | `Persisent Volume Object` | **Optional.** An object that holds an array of persistent volumes. + +#### Persistent Volume Object + +This describes a requirement for persistent, read-only or read-write storage that should be available to the containerapp on runtime. The name of this object MUST be `"persistentVolume"`. + +Despite the name, within __Kubernetes__ and __OpenShift__ this acts as a [PersistentVolumeClaim](http://kubernetes.io/v1.1/docs/user-guide/persistent-volumes.html). + +Persistent Volume is only available for the following providers: __kubernetes__ + +##### Fields + +Field Name | Type | Description +---------------- | :-------: | ------------ +name | `string` | **Required.** A name associated with the storage requirement. +accessMode | `string` | **Required.** Must be either: __ReadWriteOnce__, __ReadOnlyMany__ or __ReadWriteMany__. +size | `integer` | **Required.** Size of the volume claim. + +##### Persistent Volume Example + +```yaml +requirements: + - persistentVolume: + name: "var-log-http" + accessMode: "ReadWriteOnce" + size: 4 + - persistentVolume: + name: "var-log-https" + accessMode: "ReadOnlyMany" + size: 4 + ... +``` + +#### Artifacts Object + +The Artifacts Object describes a list of provider specific artifact items. These artifact items will be used during the installation of the containerapp to deploy to the provider. Each provider key contains a list of artifacts. + +Each artifact is a file location relative to the `Nulecule` file. + +__Optionally,__ you may _inherit_ from another compatible provider. + +##### Artifacts Example: + +```yaml +graph: + ... + artifacts: + docker: + - file://artifacts/docker/hello-apache-pod_run + kubernetes: + - file://artifacts/kubernetes/hello-apache-pod.json + openshift: + - inherit: + - kubernetes + ... +``` +## Directory Layout + +Names of files that must be present are contained in the file `files` in +the root directory of the specification. These filenames support globbing. + +A filesystem layout of a typical app is this: +``` +├── Nulecule +├── Dockerfile +├── +│ ├── ... +│ └── +└── README.md +``` + +* `Nulecule`: Container Application definition +* `Dockerfile`: standard packaging for this containerapp +* ``: directories of provider-specific files referenced in a containerapp definition file + * `PROVIDER_FILES`: provider-specific files necessary for deploying to provider +* `README.md`: information for deploying this application + + +## README.md + +The README.md is the human-readable document. It describes the containerapp in enough detail so an operator can make parameterization and other deployment decisions. + +NOTE: This is optional. It is possible for some applications to be "self-describing" through well-written descriptions and input validation. + +## Good Practices + +An implementation of the Nulecule Specification should declare what providers it supports. This should be done by adding a Label to the container image, by adding a line to the Dockerfile: +``` +LABEL io.projectatomic.nulecule.providers "kubernetes,docker,openshift" +``` + +## Conventions + +A few conventions are used in the context of Container Applications. + +### Parameters for Providers + +Each provider in the [ArtifactsObject](#artifactsObject) of the [GraphObject](#graphObject) may correspond to a containerapp level [ParamsObject](#paramsObject). + +### Version Label + +The Dockerfile must carry a Label declaring the version of the specification that is used: +``` +LABEL io.projectatomic.nulecule.specversion 0.0.2 +``` + +# Full example + +This is a full example of __all__ features of the Nulecule file. This is only used as an example and _does not necessarily work as intended_. + +```yaml +--- +specversion: 0.0.2 +id: helloworld + +metadata: + name: Hello World + appversion: 0.0.1 + description: Hello earth! + license: + - name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + foo: bar + othermetadata: + foo: bar + files: file://path/to/local/file + +graph: + - name: mariadb-centos7-atomicapp + source: docker://projectatomic/mariadb-centos7-atomicapp + + - name: helloapache-app + params: + - name: image + description: The webserver image + default: centos/httpd + - name: hostport + description: The host TCP port as the external endpoint + default: 80 + artifacts: + docker: + - file://artifacts/docker/hello-apache-pod_run + kubernetes: + - file://artifacts/kubernetes/hello-apache-pod.json + openshift: + - inherit: + - kubernetes + marathon: + - file://artifacts/marathon/helloapache.json + +requirements: + - persistentVolume: + name: "var-log-httpd" + accessMode: "ReadWriteOnce" + size: 4 +``` diff --git a/spec/README.md b/spec/README.md deleted file mode 100644 index 19b8961..0000000 --- a/spec/README.md +++ /dev/null @@ -1,371 +0,0 @@ -# Container Application Specification - -**NOTE**: This is a work in progress effort that is expected to change quickly. Feel free to join the initiative! - -#### Version 0.0.2 - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](http://www.ietf.org/rfc/rfc2119.txt). - -The Container Application Specification is licensed under [GNU Free Documentation License Version 1.3, 3 November 2008](https://www.gnu.org/copyleft/fdl.html). - -## Introduction - -The Container Application specification is a project to describe 'an Application' that is composed of a set of dependent Container Applications (containerapp). The Container Application specification defines a set of files required to describe such a containerapp. These files can then be used by other tools to deploy a containerapp. Developers may use other tools to generate most of the required containerapp files. Additional utilities can also take advantage of the resulting files, such as testing tools. - -### Versioning - -Within this specification we follow [the semantic versioning pattern](http://semver.org/spec/v2.0.0.html). - -## Revision History - -Version | Date | Notes ---- | --- | --- -0.0.2 | 2015-05-07 | close issue #35 the graph is now a list of named items -0.0.1-alpha | 2015-mm-dd | TBD -v1-alpha | 2015-04-10 | reversioned to 0.0.1-alpha - - -## Specification - -### Format - -The files describing a containerapp in accordance with the Container Application Specification are represented using [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) or [JSON](http://json.org/). - -All field names in the specification are **case sensitive**. - -By convention, the containerapp definition file is named `Nulecule`. The Nulecule is the primary file defining the containerapp and it's relationship to dependencies. - -### Data Types - -Primitive data types in the Container Application Specification are based on the types supported by the [JSON-Schema Draft 4](http://json-schema.org/latest/json-schema-core.html#anchor8). - -The formats defined by the Container Application Specification are: - -Common Name | [`type`](#dataTypeType) | [`format`](#dataTypeFormat) | Comments ------------ | ------ | -------- | -------- -integer | `integer` | `int32` | signed 64 bits -float | `number` | `float` | -string | `string` | | -byte | `string` | `byte` | -boolean | `boolean` | | -date | `string` | `date` | As defined by `full-date` - [RFC3339](http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14) -dateTime | `string` | `date-time` | As defined by `date-time` - [RFC3339](http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14) -password | `string` | `password` | Used to hint UIs the input needs to be obscured. -URL | `URL` | `URL` | As defined by `URL` - [RFC3986 Section 1.1.3](https://tools.ietf.org/html/rfc3986#section-1.1.3) - -### Terminology - -Container Application - -Provider - - -### Schema - -#### Container Application Object - -This is the root object for the specification. - -##### Fields - -Field Name | Type | Description ----|:---:|--- -id | `string` | **Required.** The machine readable id of the Container Application. -specversion | `string` | **Required.** The semantic version string of the Container Application Specification used to describe the app. The value MUST be `"0.0.2"`. -metadata | [ [MetadataObject](#metadataObject) ] | **Optional** An object holding optional metadata related to the Container Application, this may include license information or human readable information. -params | [ [ParamsObject](#paramsObject) ] | **Optional** A list of [ParamsObject](#paramsObject) that contain provider specific information. -graph | [ [GraphObject](#graphObject) ] | **Required.** A list of depending containerapps. Strings may either match a local sub directory or another containerapp-spec compliant containerapp image that can be pulled via a provider. -requirements | [ [RequirementsObject](#requirementsObject) ] | **Optional** A list of requirements of this containerapp. - - -#### Metadata Object - -Metadata for the Container Application. - -##### Fields - -Field Name | Type | Description ----|:---:|--- -name | `string` | **Optional** A human readable name of the containerapp. -appversion | `string` | **Optional** The semantic version string of the Container Application. -description | `string` | **Optional** A human readable description of the Container Application. This may contain information for the deployer of the containerapp. -license | [License Object](#licenseObject) | **Optional** The license information for the containerapp. -arbitrary_data | `string` | **Optional** Arbitrary `key: value` pair(s) of metadata. May contain nested objects. - -##### Metadata Object Example: - -```yaml -name: myapp -appversion: 1.0.0 -description: description of myapp -foo: bar -othermetadata: - foo: bar - files: file://path/to/local/file -``` - -```js -{ - "name": "myapp", - "appversion": "1.0.0", - "description": "description of myapp", - "foo": "bar", - "othermetadata": { - "foo": "bar", - "files": "file://path/to/local/file" - } -} -``` - -#### License Object - -License information for the Container Application. - -##### Fields - -Field Name | Type | Description ----|:---:|--- -name | `string` | **Required.** The human readable license name used for the Container Application, no format imposed. -url | `string` | **Optional** A URL to the license used for the API. MUST be in the format of a URL. - -##### License Object Example: - - -```yaml -name: Apache 2.0 -url: http://www.apache.org/licenses/LICENSE-2.0.html -``` -```js -{ - "name": "GNU GPL, Version 3", - "url": "https://www.gnu.org/copyleft/gpl.html" -} -``` - - -#### Graph Object - -The graph is a list of items (containerapps) the Container Application depends on. - -##### Fields of a Graph Item Object - -Field Name | Type | Description ----|:---:|--- -name | `string` | **Required.** The name of the depending Container Application. -source | `URL` | **Optional** Source location of the Container Application, the source MUST be specified by a valid URL. If source is present, all other fields SHALL be ignored. -params | [ [ParamsObject](#paramsObject) ] | **Optional** A list of [ParamsObject](#paramsObject) that contain provider specific information. If params is present, source field SHALL be ignored. -artifacts | [ [ArtifactsObject](#artifactsObject) ] | **Optional** A list of [ArtifactsObject](#artifactsObject) that contain providr specific information. If artifacts is present, source field SHALL be ignored. - -##### Graph Item Object Example: - -```yaml ---- -name: atomicapp-zabbix-mongodb -source: uri://registry.devops.example.com -# if no "artifacts" is specified, then it is an external Atomic App to be pulled -# and installed from the specified source -``` - -```js -{ -"name": "atomicapp-zabbix-mongodb", -"source": "uri://registry.devops.example.com" -} -``` - -#### Parameters Object - -A list of Parameters the containerapp requires, has set some defaults for or needs user input. - -##### Fields - -Field Name | Type | Description ----|:---:|--- -name| `string` | **Required.** The name of the parameter. -description | `string` | **Required.** A human readable description of the parameter. -constraints | [ConstraintObject](#constraintObject) | **Optional** An optional definition of constraints to the parameter. -default | `string` | **Optional** An optional default value for the parameter. -hidden | `string` | **Optional** An optional boolean signifying the parameter should be obscured when displayed. - -##### Parameters Object Example: - -```yaml -name: password -description: mongoDB Admin password -hidden: true -constraints: - - allowed_pattern: "[A-Z0-9]+" - description: Must consist of characters and numbers only. -``` -```js -{ - "name": "password", - "description": "mongoDB Admin password", - "hidden": true, - "constraints": [ - { - "allowed_pattern": "[A-Z0-9]+", - "description": "Must consist of characters and numbers only." - } - ] -} -``` - -#### Constraint Object - -Constraints to the parameter. - -##### Fields - -Field Name | Type | Description ----|:---:|--- -allowed_pattern | `string` | **Required.** A regexp declaring the allowed pattern. -description | `string` | **Required.** A human readable description of the parameter. - - - -#### Requirements Object - -The list of requirements of the Container Application. It may be [Storage Requirement Objects](#storageRequirementsObject) (for a persistent Volume). - - -#### Storage Requirements Object - -This describes a requirement for persistent, read-only or read-write storage that should be available to the containerapp on runtime. The name of this object MUST be `"persistentVolume"`. - -##### Fields of Storage Requirement - -Field Name | Type | Description ----|:---:|--- -name | `string` | **Required.** A name associated with the storage requirement. -accessModes | `string` | **Required.** May be `"ReadWrite"` or `"ReadOnly"`. -size | `integer` | **Required.** Size of required the storage. - -##### Storage Requirement Example: - -```yaml ---- -- persistentVolume: - name: "var-lib-mongodb-data" - accessMode: "ReadWrite" - size: 4 # GB by default -``` -```js - { - "persistentVolume": { - "name": "var-lib-mongodb-data", - "accessMode": "ReadWrite", - "size": 4 - } - } -``` - - -#### Artifacts Object - -The Artifacts Object describes a list of provider specific artifact items. These artifact items will be used during installation of the containerapp to deploy it to the provider. Each provider key contains a list of artifacts. Each artifact list item is either a `URL` string or a [source control repository object](#repositoryObject). - -* URL: must be a URL string prepended by URI type such as `http://`, `https://`, `file:` (relative path) or `file://` (absolute path). URI type `file:` may be a single file or a directory path to multiple files. Directories must end with a trailing slash such as `file:relative/path/to/multiple/artifact/files/`. -* [SourceControlRepositoryObject](#repositoryObject) - -##### Artifacts Example: - -```yaml ---- -artifacts: # list of local or remote files or remote repository path to be processed by the provider selected at install-time - kubernetes: - - source: https://github.com/aweiteka/kube-files.git - tag: release-1 - openshift: - - file:relative/path/openshift/artifacts/ - - https://example.com/openshift/strategies.json - - inherit: - - kubernetes -``` -```js -{ - "artifacts": { - "kubernetes": [ - { - "source": "https://github.com/aweiteka/kube-files.git", - "path": "/artifacts/kubernetes/", - "tag": "release-1" - } - ], - "openshift": [ - "file:relative/path/openshift/artifacts/", - "https://example.com/openshift/strategies.json", - { - "inherit": [ - "kubernetes" - ] - } - ] - } -} -``` - -#### Source Control Repository Object - -Source Control Repository Object for artifact sources. - -##### Fields of a Source Control Repository Object - -Field Name | Type | Description ----|:---:|--- -source | `URL` | **Required** Source location of the source control repository. The source MUST be specified by a valid URL. -path | `string` | **Optional** The path to a specific artifact file or directory of artifact files. Default value is "/" which would reference all of the files in the repository. -type | `string` | **Optional** The source control type. Default value is "git". -branch | `string` | **Optional** The source control branch. Default value is "master". -tag | `string` | **Optional** The source control tag. - - -## Directory Layout - -Names of files that must be present are contained in the file `files` in -the root directory of the specification. These filenames support globbing. - -A filesystem layout of a typical app is this: -``` -├── Nulecule -├── Dockerfile -├── -│ ├── ... -│ └── -└── README.md -``` - -* `Nulecule`: Container Application definition -* `Dockerfile`: standard packaging for this containerapp -* ``: directories of provider-specific files referenced in a containerapp definition file - * `PROVIDER_FILES`: provider-specific files necessary for deploying to provider -* `README.md`: information for deploying this application - - -## README.md - -The README.md is the human-readable document. It describes the containerapp in enough detail so an operator can make parameterization and other deployment decisions. - -NOTE: This is optional. It is possible for some applications to be "self-describing" through well-written descriptions and input validation. - -## Good Practices - -An implementation of the Nulecule Specification should declare what providers it supports. This should be done by adding a Label to the container image, by adding a line to the Dockerfile: -``` -LABEL io.projectatomic.nulecule.providers "kubernetes,docker,openshift" -``` - -## Conventions - -A few conventions are used in the context of Container Applications. - -### Parameters for Providers - -Each provider in the [ArtifactsObject](#artifactsObject) of the [GraphObject](#graphObject) may correspond to a containerapp level [ParamsObject](#paramsObject). - -### Version Label - -The Dockerfile must carry a Label declaring the version of the specification that is used: -``` -LABEL io.projectatomic.nulecule.specversion 0.0.2 -``` diff --git a/spec/constraint.json b/spec/constraint.json deleted file mode 100644 index 6d7f747..0000000 --- a/spec/constraint.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "Constraint", - "description": "Constraint to the parameter.", - "type": "array", - "items": { - "type": "object", - "required": [ "allowed_pattern", "description" ], - "properties": { - "allowed_pattern": { - "description": "A regular expression pattern.", - "type": "string", - "default": "null" - }, - "description": { - "description": "A human readable description of the constraint.", - "type": "string", - "default": "null" - } - } - } -} diff --git a/spec/examples/template/Dockerfile b/spec/examples/template/Dockerfile deleted file mode 100644 index b0e9145..0000000 --- a/spec/examples/template/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM projectatomic/atomicapp:0.3.0 - -MAINTAINER Your Name - -LABEL io.projectatomic.nulecule.specversion 0.0.2 -LABEL io.projectatomic.nulecule.providers = "provider1,provider2" - -ADD /Nulecule /Dockerfile /application-entity/ -ADD /artifacts /application-entity/artifacts diff --git a/spec/examples/template/Nulecule b/spec/examples/template/Nulecule deleted file mode 100644 index cbf6164..0000000 --- a/spec/examples/template/Nulecule +++ /dev/null @@ -1,38 +0,0 @@ ---- -specversion: "0.0.2" - -id: 191131-abcd -metadata: - name: "my app" - appversion: v1.0.0 - description: "some application" - license: - name: "License 2.0" - url: www.example.com/license - -graph: - - name: somedb - source: "docker://registry.example.com/some/database" - - name: mycode - params: - - name: password - description: passphrase - - name: username - constraints: - - allowed_pattern: "[A-Z0-9]+" - description: "Must consist of characters and numbers only." - description: username - artifacts: - provider1: - - source: "https://github.com/foo/bar/provider1.git" - path: /my/provider/files/ - tag: release-1 - provider2: - - "file:artifacts/provider2/" - - inherit: - - provider1 -requirements: - - persistentVolume: - accessMode: ReadWrite - name: var-lib-data - size: 4 diff --git a/spec/examples/template/artifacts/provider1/pod.json b/spec/examples/template/artifacts/provider1/pod.json deleted file mode 100644 index e69de29..0000000 diff --git a/spec/examples/template/artifacts/provider1/service.json b/spec/examples/template/artifacts/provider1/service.json deleted file mode 100644 index e69de29..0000000 diff --git a/spec/examples/template/artifacts/provider2/file.json b/spec/examples/template/artifacts/provider2/file.json deleted file mode 100644 index e69de29..0000000 diff --git a/spec/files b/spec/files deleted file mode 100644 index 9c3dd39..0000000 --- a/spec/files +++ /dev/null @@ -1,2 +0,0 @@ -Dockerfile -Nulecule diff --git a/spec/graph.json b/spec/graph.json deleted file mode 100644 index a53949a..0000000 --- a/spec/graph.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "Graph", - "description": "A list of components that constitute this Container Application. Components are either container-based services or other Container Applications. Components that are container-based services are specified as a collection of artifacts for providers that can accept a parameters specified by the deployer. These artifacts are references to files located in local sub-directories. Components that are other Container Applications are specified as URLs.", - "type": "array", - "items" : { - "$ref": "#/definitions/component" - }, - - "definitions": { - "component": { - "description": "ID of a component", - "type": "object", - "required": [ "name" ], - "properties": { - "name": { - "description": "The name of the component.", - "type": "string", - "default": "null" - }, - "source": { - "description": "If the component is another Container Application, source MUST be a valid URL to the source location. If source is present, all other fields SHALL be ignored.", - "type": "string", - "default": "null" - }, - "params": { - "description": "A list of ParamsObject that contain information to be used by providers in conjunction with their ArtifactsObject. If params is present, the source field SHALL be ignored.", - "type": "array", - "items": { - "$ref": "file:param.json" - } - }, - "artifacts": { - "description": "A list of ArtifactsObject that contain provider specific information. If artifacts is present, the source field SHALL be ignored.", - "type": "object", - "additionalProperties": { - "$ref": "file:provider.json" - } - } - } - } - } -} diff --git a/spec/license.json b/spec/license.json deleted file mode 100644 index 1fae538..0000000 --- a/spec/license.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "License", - "description": "License information for the Container Application.", - "type": "object", - "required": [ "name" ], - "properties": { - "name": { - "description": "The human readable license name used for the Container Application, no format imposed.", - "type": "string", - "default": "null" - }, - "url": { - "description": "A URL to the license used for the API. MUST be in the format of a URL.", - "type": "string", - "default": "null" - } - } -} diff --git a/spec/metadata.json b/spec/metadata.json deleted file mode 100644 index 30c3388..0000000 --- a/spec/metadata.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "Metadata", - "description": "An object holding optional metadata related to the Container Application. This will typically include the container application name, version, description, license information and other human readable information.", - "type": "object", - "properties": { - "name": { - "description": "A human readable name of the containerapp.", - "type": "string", - "default": "null" - }, - "appversion": { - "description": "The semantic version string of the Container Application.", - "type": "string", - "default": "null" - }, - "description": { - "description": "A human readable description of the Container Application. This may contain information for the deployer of the containerapp.", - "type": "string", - "default": "null" - }, - "license": { - "$ref": "file:license.json" - } - } -} diff --git a/spec/param.json b/spec/param.json deleted file mode 100644 index 18f9811..0000000 --- a/spec/param.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "Parameter", - "description": "Name of the parameter as used in artifacts", - "type": "object", - "required": [ "name", "description" ], - "properties": { - "name": { - "description": "", - "type": "string", - "default": "null" - }, - "description": { - "description": "A human readable description of the parameter.", - "type": "string", - "default": "null" - }, - "constraints": { - "$ref": "file:constraint.json" - }, - "default": { - "description": "An optional default value for the parameter.", - "type": "string", - "default": "null" - }, - "hidden": { - "description": "An optional boolean signifying the parameter should be obscured when displayed.", - "type": "boolean", - "default": false - } - } -} diff --git a/spec/provider.json b/spec/provider.json deleted file mode 100644 index 9939975..0000000 --- a/spec/provider.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "Provider", - "description": "A provider is a deployment platform or orchestrator.", - "type": "array", - "items": { - "oneOf": [ { "$ref": "#/definitions/path" }, { "$ref": "#/definitions/repository" }, { "$ref": "#/definitions/inheritance" } ] - }, - - "definitions": { - "path": { - "description": "Path to the artifact", - "type": "string", - "default": "null" - }, - "repository": { - "type": "object", - "properties": { - "source": { - "name": "source", - "description": "Source location of the source control repository. The source MUST be specified by a valid URL.", - "type": "string", - "default": "null" - }, - "path": { - "name": "path", - "description": "The path to a specific artifact file or directory of artifact files. Default value is '/' which would reference all of the files in the repository.", - "type": "string", - "default": "/" - }, - "type": { - "name": "type", - "description": "The source control type. Default value is 'git'.", - "type": "string", - "default": "git" - }, - "branch": { - "name": "branch", - "description": "The source control branch. Default value is 'master'.", - "type": "string", - "default": "master" - }, - "tag": { - "name": "tag", - "description": "The source control tag.", - "type": "string", - "default": "null" - } - } - }, - "inheritance": { - "type": "object", - "properties": { - "inherit": { - "name": "inherit", - "description": "List of components whose artifacts will be added to the list of artifacts for the provider.", - "type": "array" - } - } - } - } -} diff --git a/spec/requirement.json b/spec/requirement.json deleted file mode 100644 index fa97fe3..0000000 --- a/spec/requirement.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "Requirements", - "description": "Requirement objects", - "type": "array", - "items": { - "oneOf": [ - { "$ref": "file:requirements/persistentvolume.json" } - ] - } -} diff --git a/spec/requirements/persistentvolume.json b/spec/requirements/persistentvolume.json deleted file mode 100644 index 70b65a1..0000000 --- a/spec/requirements/persistentvolume.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "PersistentVolume", - "description": "This describes a requirement for persistent, read-only or read-write storage that should be available to the Container Application at runtime. The name of this object MUST be 'persistentVolume'", - "type": "object", - "properties": { - "persistentVolume": { - "type": "object", - "required": [ "name", "accessMode", "size" ], - "properties": { - "name": { - "description": "A name associated with the storage requirement.", - "type": "string", - "default": "null" - }, - "accessMode": { - "description": "The access mode, read-write or read-only, for the storage", - "type": "string", - "enum": [ - "ReadWrite", - "ReadOnly" - ] - }, - "size": { - "description": "Size of the storage.", - "type": "number", - "minimum": 0 - } - } - } - }, - "additionalProperties": false -} diff --git a/spec/schema.json b/spec/schema.json deleted file mode 100644 index e7e2d56..0000000 --- a/spec/schema.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - - "title": "Schema", - "version": "0.0.2", - "description": "The Container Application specification defines a set of configuration files that describe a Container Application. A Container Application is composed of a set of container-based services and/or other Container Applications that together provide an application. These configuration files can be used by tools to deploy the application in an automated way or with customizations as specified by the deployer. Developers tools can generate most of the required files and utilities, such as testing tools, can take advantage of these files.", - "required": [ "id", "specversion", "graph" ], - "properties": { - "id": { - "description": "The machine readable id of the Container Application.", - "type": "string", - "default": "null" - }, - "specversion": { - "description": "The semantic version string of the Container Application Specification used to describe the app. The value SHOULD be '0.0.2'.", - "type": "string", - "default": "0.0.2" - }, - "metadata": { - "$ref": "file:metadata.json" - }, - "params": { - "description": "A list of ParamsObject that contain information in the global context of the application, accessible to it's child graph items.", - "type": "array", - "items": { - "$ref": "file:param.json" - } - }, - "graph": { - "$ref": "file:graph.json" - }, - "requirements": { - "$ref": "file:requirement.json" - } - } -}