diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b53c5a99..a7a09e53 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,48 @@ which is hosted in the [Project Atomic Organization](https://github.com/projecta These are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request. +## Initial dev environment + +First of all, clone the github repository: `git clone https://github.com/projectatomic/atomicapp`.. + +### Installing Atomic App locally +Simply run + +``` +make install +``` + +If you want to do some changes to the code, I suggest to do: + +``` +cd atomicapp +export PYTHONPATH=`pwd`:$PYTHONPATH +alias atomicapp="python `pwd`/atomicapp/cli/main.py" +``` + +### Building for containerized execution +``` +docker build -t [TAG] . +``` + +Use 'docker build' to package up the application and tag the resulting image. + +### Fetch and run +``` +atomicapp [--dry-run] [-v] [-a answers.conf] fetch|run|stop|genanswers [--provider docker] [--destination DST_PATH] APP|PATH +``` + +Pulls the application and its dependencies. If the last argument is +existing path, it looks for `Nulecule` file there instead of pulling anything. + +* `--provider docker` Use the Docker provider within the Atomic App +* `--destination DST_PATH` Unpack the application into given directory instead of current directory +* `APP` Name of the image containing the application (ex. `projectatomic/apache-centos7-atomicapp`) +* `PATH` Path to a directory with installed (ex. result of `atomicapp fetch...`) app + +Action `run` performs `fetch` prior to its own tasks if an `APP` is provided. Otherwise, it will use its respective `PATH`. When `run` is selected, providers' code is invoked and containers are deployed. + + ## Submitting Issues * You can create an issue [here](https://github.com/projectatomic/atomicapp/issues/new), include as many details as possible with your report. @@ -33,13 +75,11 @@ Before you submit your pull request consider the following guidelines: * Include documentation that either describe a change to a behavior of atomicapp or the changed capability to an end user of atomicapp. * Commit your changes using **a descriptive commit message**. If you are fixing an issue please include something like 'this closes issue #xyz'. -* Additionally think about implementing a git hook, as flake8 is part of the [travis-ci tests](https://travis-ci.org/projectatomic/atomicapp) it will help you pass the CI tests. +* Make sure your tests pass! As we use [travis-ci](https://travis-ci.org/projectatomic/atomicapp) with __flake8__ it's recommended to run both commands before submitting a PR. ```shell - $ cat .git/hooks/pre-push - #!/bin/bash - - flake8 -v atomicapp + make syntax-check + make test ``` * Push your branch to GitHub: diff --git a/README.md b/README.md index 79585f2e..d70ce9e6 100644 --- a/README.md +++ b/README.md @@ -1,87 +1,102 @@ # Atomic App -Atomic App is a reference implementation of the [Nulecule specification](https://github.com/projectatomic/nulecule). It can be used to bootstrap packaged container environments and then run them. Atomic App is designed to be ran within a container. +![](docs/images/logo.png "Project Atomic") -Examples of this tool may be found within the [Nulecule library repo](https://github.com/projectatomic/nulecule/tree/master/examples). +Atomic App is a reference implementation of the [Nulecule](https://github.com/projectatomic/nulecule) specification. Packaged Atomic App containers are "Nuleculized" and each component of the package is a "Nulecule". -## Getting Started +Atomic App is used to bootstrap packaged container environments and run them on multiple container orchestrators. It is designed from the ground-up to be portable and provider pluggable. -Atomic App itself is packaged as a container. End-users typically do not install the software from source. Instead use the `atomicapp` container as the `FROM` line in a Dockerfile and package your application on top. For example: + - __A "packaged installer" for all container-based environments and applications.__ Replace all those bash and Ansible scripts with one container-based deployment tool. -``` -FROM projectatomic/atomicapp - -MAINTAINER Your Name - -ADD /Nulecule /Dockerfile README.md /application-entity/ -ADD /artifacts /application-entity/artifacts -``` + - __Target multiple providers:__ Specify the provider you want the Atomic App to run on. It supports Kubernetes, OpenShift, Mesos+Marathon and Docker. -For more information see the [Nulecule getting started guide](https://github.com/projectatomic/nulecule/blob/master/docs/getting-started.md). + - __Inherit already packaged containers:__ Create composite applications by referencing other Nulecule-compliant applications. For example, plugging in an alternative well-orchestrated database in another referenced container image. -## Developers + - __Fetch and run entire environments:__ Use `atomicapp fetch` and `atomicapp run` to run pre-packaged Nuleculized containers. -First of all, clone the github repository: `git clone https://github.com/projectatomic/atomicapp`. +## Installing Atomic App +From Linux: +```sh +git clone https://github.com/projectatomic/atomicapp && cd atomicapp +make install +``` -### Installing Atomic App locally -Simply run +_or_ -``` +Download a pre-signed .tar.gz from [download.projectatomic.io](https://download.projectatomic.io) / [GitHub](https://github.com/projectatomic/atomicapp/releases): +```sh +export RELEASE=0.4.2 +wget https://github.com/projectatomic/atomicapp/releases/download/$RELEASE/atomicapp-$RELEASE.tar.gz +tar -xvf atomicapp-$RELEASE.tar.gz && cd atomicapp-$RELEASE.tar.gz make install ``` -If you want to do some changes to the code, I suggest to do: +## Documentation -``` -cd atomicapp -export PYTHONPATH=`pwd`:$PYTHONPATH -alias atomicapp="python `pwd`/atomicapp/cli/main.py" -``` +This README contains some high level overview information on Atomic App. The detailed documentation for Atomic App resides in the [docs](docs) directory. The index provided conveniently links to each section below: -### Building for containerized execution -``` -docker build -t [TAG] . -``` +1. [Quick start](docs/quick_start.md) +2. [Getting started](docs/start_guide.md) +3. [Providers](docs/providers.md) + 1. [Docker](docs/providers/docker/overview.md) + 2. [Kubernetes](docs/providers/kubernetes/overview.md) + 3. [OpenShift](docs/providers/openshift/overview.md) +4. [CLI](docs/cli.md) +5. [Nulecule file](docs/nulecule.md) +6. [Atomic App lifecycle](docs/atomicapp_lifecycle.md) +7. [File handling](docs/file_handling.md) +8. [Specification coverage](docs/spec_coverage.md) +9. [Contributing](CONTRIBUTING.md) +10. [Dependencies](docs/requirements.md) -Use 'docker build' to package up the application and tag the resulting image. -### Fetch and run -``` -atomicapp [--dry-run] [-v] [-a answers.conf] fetch|run|stop|genanswers [--provider docker] [--destination DST_PATH] APP|PATH -``` +## Getting started -Pulls the application and its dependencies. If the last argument is -existing path, it looks for `Nulecule` file there instead of pulling anything. +Atomic App 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/). -* `--provider docker` Use the Docker provider within the Atomic App -* `--destination DST_PATH` Unpack the application into given directory instead of current directory -* `APP` Name of the image containing the application (ex. `projectatomic/apache-centos7-atomicapp`) -* `PATH` Path to a directory with installed (ex. result of `atomicapp fetch...`) app +__Detailed instructions on [getting started](docs/start_guide.md) are available.__ Alternatively, use the [quick start guide](docs/quick_start.md) to get a Nuleculized application running immediately. -Action `run` performs `fetch` prior to its own tasks if an `APP` is provided. Otherwise, it will use its respective `PATH`. When `run` is selected, providers' code is invoked and containers are deployed. +An extended guide on the `Nulecule` file format is [also available](docs/nulecule.md). -## Providers +## Real-world examples +Atomic App can be used to launch a cluster of containers (application servers, databases, etc.). -Providers represent various deployment targets. They can be added by placing the artifact within the respective in `provider/` folder. For example, placing `deploy_pod.yml` within `providers/kubernetes/`. For a detailed description of all providers available see [docs/providers.md](docs/providers.md). +For a list of already packaged examples, visit the [nulecule-library](https://github.com/projectatomic/nulecule-library) repo. -## Dependencies +## Providers -See [REQUIREMENTS](https://github.com/projectatomic/atomicapp/blob/master/docs/requirements.md) for current Atomic App dependencies. +We currently support: -##Communication channels + - Docker + - Kubernetes + - OpenShift 3 + - Marathon (Mesos) -* IRC: #nulecule (On Freenode) -* Mailing List: [container-tools@redhat.com](https://www.redhat.com/mailman/listinfo/container-tools) +Providers represent various deployment targets. They can be added by placing the artifact within the respective in `artifacts/` folder. For example, placing `deploy_pod.yml` within `artifacts/kubernetes/`. -# The Badges +For a detailed description of all providers available see [docs/providers.md](docs/providers.md). +## Contributing to Atomic App [![Code Health](https://landscape.io/github/projectatomic/atomicapp/master/landscape.svg?style=flat)](https://landscape.io/github/projectatomic/atomicapp/master) [![Build Status](https://travis-ci.org/projectatomic/atomicapp.svg?branch=master)](https://travis-ci.org/projectatomic/atomicapp) [![Coverage Status](https://coveralls.io/repos/projectatomic/atomicapp/badge.svg?branch=master&service=github)](https://coveralls.io/github/projectatomic/atomicapp?branch=master) [![Issue Stats](http://issuestats.com/github/projectatomic/atomicapp/badge/pr)](http://issuestats.com/github/projectatomic/atomicapp) [![Issue Stats](http://issuestats.com/github/projectatomic/atomicapp/badge/issue)](http://issuestats.com/github/projectatomic/atomicapp) -# Copyright +First of all, awesome! We have [a development guide to help you get started!](CONTRIBUTING.md) + +If you have any issues or get stuck, feel free to open a GitHub issue or reach us at our communication channels (see below). + +## Dependencies + +See [REQUIREMENTS.md](docs/requirements.md) for a list of current Atomic App dependencies. + +## Communication channels + +* IRC: __#nulecule__ on irc.freenode.net +* Mailing List: [container-tools@redhat.com](https://www.redhat.com/mailman/listinfo/container-tools) + +## Copyright Copyright (C) 2016 Red Hat Inc. diff --git a/docs/images/logo.png b/docs/images/logo.png new file mode 100644 index 00000000..a28fc9c0 Binary files /dev/null and b/docs/images/logo.png differ diff --git a/docs/nulecule.md b/docs/nulecule.md new file mode 100644 index 00000000..255bee92 --- /dev/null +++ b/docs/nulecule.md @@ -0,0 +1,240 @@ +# Nulecule file + +Atomic App implements version `0.0.2` of the [Nulecule specification](https://github.com/projectatomic/nulecule/tree/master/spec). + +A `Nulecule` file format can either be `json` or `yaml`. + +### 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 + ... +``` + +# 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/docs/quick_start.md b/docs/quick_start.md new file mode 100644 index 00000000..92e61648 --- /dev/null +++ b/docs/quick_start.md @@ -0,0 +1,153 @@ +## Using Atomic App + +Prerequisite: Before proceeding, make sure you either have a Kubernetes, OpenShift or Docker environment setup and ready. + +You can either use Atomic App on your own OS or in a container via the `atomic` command on Atomic hosts. + +In order to use Atomic App on Project Atomic hosts we use the `INSTALL` and `RUN` label functionality with [atomic cli](https://github.com/projectatomic/atomic). + +With the exception of the `atomic stop` command all functionality is essentially the same. + +### Quickstart: Atomic App on bare metal + +__Running Apache on Docker:__ +```sh +▶ sudo atomicapp run projectatomic/helloapache --provider=docker +2016-02-25 16:06:38,298 - [INFO] - main.py - Action/Mode Selected is: run +2016-02-25 16:06:38,299 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to /var/lib/atomicapp/projectatomic-helloapache-7c32c1632a7b +2016-02-25 16:06:41,904 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-02-25 16:06:41,904 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to /var/lib/atomicapp/projectatomic-helloapache-7c32c1632a7b +20af2e6e33d10d26aa98d6e63c70de5fd55bfe14b9cc782e1312afe441ef7130 +2016-02-25 16:06:42,231 - [INFO] - docker.py - Deploying to provider: Docker +5d6938439d50c21251507b26c73f5e65f102f2b99e183002ef2ec21414c4ee78 + +Your application resides in /var/lib/atomicapp/projectatomic-helloapache-7c32c1632a7b +Please use this directory for managing your application + +▶ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +5d6938439d50 centos/httpd "/run-httpd.sh" 3 seconds ago Up 1 seconds 0.0.0.0:80->80/tcp default_centos-httpd_ec75a2fe2a50 +``` + +__Runnning Apache on Kubernetes:__ +```sh +▶ sudo atomicapp run projectatomic/helloapache +2016-02-25 15:03:04,341 - [INFO] - main.py - Action/Mode Selected is: run +2016-02-25 15:03:04,343 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to /var/lib/atomicapp/projectatomic-helloapache-c0dd79b5e757 +2016-02-25 15:03:07,983 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-02-25 15:03:07,984 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to /var/lib/atomicapp/projectatomic-helloapache-c0dd79b5e757 +886e10a3244f982f3302ab9058ab7b377c6f83e2cf63f001e1ba011358d0b471 +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - Using namespace default +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - trying kubectl at /usr/bin/kubectl +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - trying kubectl at /usr/local/bin/kubectl +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - found kubectl at /usr/local/bin/kubectl +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - Deploying to Kubernetes +... + +Your application resides in /var/lib/atomicapp/projectatomic-helloapache-c0dd79b5e757 +Please use this directory for managing your application + +▶ kubectl get po +NAME READY STATUS RESTARTS AGE +helloapache 1/1 Running 0 2m +k8s-etcd-127.0.0.1 1/1 Running 0 1d +k8s-master-127.0.0.1 4/4 Running 0 1d +k8s-proxy-127.0.0.1 1/1 Running 0 1d +``` + +__Fetch, edit and run Apache on Kubernetes:__ +```sh +▶ mkdir ./localdir + +▶ sudo atomicapp fetch projectatomic/helloapache --destination ./localdir/ +2016-02-25 15:35:41,439 - [INFO] - main.py - Action/Mode Selected is: fetch +2016-02-25 15:35:41,440 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to helloapache +2016-02-25 15:35:45,067 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-02-25 15:35:45,067 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to helloapache +c12d2047fab44f2906b9cbee3ac86c6c6499921ce33a90085e8765491b44f447 + +Your application resides in localdir +Please use this directory for managing your application + +▶ cd localdir + +▶ cat Nulecule +... + - name: hostport + description: The host TCP port as the external endpoint + default: 80 +... + +▶ vim Nulecule # edit port 80 to 8080 + +▶ cat Nulecule +... + - name: hostport + description: The host TCP port as the external endpoint + default: 8080 +... + +▶ sudo atomicapp run . + +OR + +▶ docker build -t myapp +▶ sudo atomicapp run myapp +``` + +### Quickstart: Atomic App on Atomic Host + +__Running Apache on Docker:__ +```sh +▶ sudo atomic run projectatomic/helloapache --provider=docker +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache run --provider=docker +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache run --provider=docker +2016-03-01 20:54:37,617 - [INFO] - main.py - Action/Mode Selected is: run +2016-03-01 20:54:37,618 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to /host/var/lib/atomicapp/projectatomic-helloapache-a68057164f09 +2016-03-01 20:54:38,357 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-03-01 20:54:38,358 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to /host/var/lib/atomicapp/projectatomic-helloapache-a68057164f09 +6eedd332f9938c7b4bacca694fdc77309ca5b43aabb05a1cb644ff8a0b713012 +2016-03-01 20:54:38,558 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:54:38,558 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:54:38,602 - [INFO] - docker.py - Deploying to provider: Docker +a98d9a3305496803c38a90a9ef65c52030dc23dae4b04f36ce167ff98335395f + +Your application resides in /var/lib/atomicapp/projectatomic-helloapache-a68057164f09 +Please use this directory for managing your application +``` + +__Runnning Apache on Kubernetes:__ +```sh +▶ sudo atomic run projectatomic/helloapache +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache run +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache run +2016-03-01 20:58:03,396 - [INFO] - main.py - Action/Mode Selected is: run +2016-03-01 20:58:03,397 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to /host/var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +2016-03-01 20:58:04,153 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-03-01 20:58:04,153 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to /host/var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +c85cbb2d28857f2b283e23a72a70e077daceeb2b72f6964605af6f7efa8fbc2f +2016-03-01 20:58:04,387 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:58:04,388 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - Using namespace default +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - trying kubectl at /host/usr/bin/kubectl +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - trying kubectl at /host/usr/local/bin/kubectl +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - found kubectl at /host/usr/local/bin/kubectl +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - Deploying to Kubernetes + +Your application resides in /var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +Please use this directory for managing your application +``` + +__Stopping Apache on Kubernetes:__ +```sh +▶ sudo atomic stop projectatomic/helloapache /var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache stop /var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +2016-03-01 20:59:57,067 - [INFO] - main.py - Action/Mode Selected is: stop +2016-03-01 20:59:57,075 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:59:57,075 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - Using namespace default +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - trying kubectl at /host/usr/bin/kubectl +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - trying kubectl at /host/usr/local/bin/kubectl +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - found kubectl at /host/usr/local/bin/kubectl +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - Undeploying from Kubernetes +``` diff --git a/docs/start_guide.md b/docs/start_guide.md new file mode 100644 index 00000000..c47692c2 --- /dev/null +++ b/docs/start_guide.md @@ -0,0 +1,288 @@ +# Getting Started + +This is a thorough start guide to show you each detail of an Atomic App. Teaching you the basic commands as well as the generation of your first Atomic App. + +## Basic commands + +The __four__ basic commands of atomicapp are: + +__atomicapp fetch__: Retrieving a packaged container and exporting it to a directory. + +ex. `atomicapp fetch projectatomic/helloapache` + +__atomicapp run__: Running a packaged container on a specified provider. Unless a directory is specified, `run` will also perform `fetch`. + +ex. `atomicapp run projectatomic/helloapache --provider=kubernetes` + +__atomicapp stop__: Stopping a deployed Nulecule on a specified provider. Whether you're using Kubernetes, OpenShift or Docker, Atomic App will stop the containers. + +ex. `atomicapp stop ./myappdir --provider=kubernetes` + +__atomicapp genanswers__: By examing the `Nulecule` file. Atomic App will generate an `answers.conf` file to be used for non-interactive deployment. + +ex. `atomicapp genanswers ./myappdir` + +For more detailed information as well as a list of all parameters, use `atomicapp --help` on the command line. Alternatively, you can read our [CLI doc](docs/cli.md). + +## Atomic App on Project Atomic hosts + +If you are on a [Project Atomic host](https://projectatomic.io/download) you can interact with `atomicapp` via the `atomic` cli command. + +Some commands for `atomicapp` on an atomic host are a bit different. + +However. Regardless of the `atomic run` command, a `--mode` can be passed to change the functionality of the command. + +`atomicapp fetch projectatomic/helloapache` + +vs + +`atomic run projectatomic/helloapache --mode fetch` + +`atomicapp run projectatomic/helloapache` + +vs + +`atomic run projectatomic/helloapache` + +`atomicapp stop ./myappdir` + +vs + +`atomic stop projectatomic/helloapache ./myappdir` + +`atomicapp genanswers ./myappdir` + +vs + +`atomic run projectatomic/helloapache ./myappdir --mode genanswers` + +## Building your first Atomic App + +A typical Atomic App or "Nulecule" container consists of the following files: +```sh +~/helloapache +▶ tree +. +├── answers.conf.sample +├── artifacts +│   ├── docker +│   │   └── hello-apache-pod_run +│   ├── kubernetes +│   │   └── hello-apache-pod.json +│   └── marathon +│   └── helloapache.json +├── Dockerfile +├── Nulecule +└── README.md +``` + +We will go through each file and folder as we build our first Atomic App container. + +For this example, we will be using the [helloapache](https://github.com/projectatomic/nulecule-library/tree/master/helloapache) example from the [nulecule-library](https://github.com/projectatomic/nulecule-library) repo. + +In order to follow along, fetch the container and `cd` into the directory: +```sh +atomicapp fetch --destination localdir projectatomic/helloapache +cd localdir +``` + +### ./localdir/Dockerfile +Atomic App itself is packaged as a container. End-users typically do not install the software from source, instead using the `atomicapp` container as the `FROM` line in a Dockerfile and packaging your application on top. For example: + + +```Dockerfile +FROM projectatomic/atomicapp + +MAINTAINER Your Name + +ADD /Nulecule /Dockerfile README.md /application-entity/ +ADD /artifacts /application-entity/artifacts +``` + +Within `helloapache` we specify a bit more within our labels: +```Dockerfile +FROM projectatomic/atomicapp:0.4.2 + +MAINTAINER Red Hat, Inc. + +LABEL io.projectatomic.nulecule.providers="kubernetes,docker,marathon" \ + io.projectatomic.nulecule.specversion="0.0.2" + +ADD /Nulecule /Dockerfile README.md /application-entity/ +ADD /artifacts /application-entity/artifacts +``` + +__Optionally__, you may indicate what providers you specifically support via the Docker LABEL command. + +__NOTE:__ The Dockerfile you supply here is for building a Nuleculized container image (often called an 'Atomic App'). It is not the Dockerfile you use to build your upstream Docker image. The actual `atomicapp` code should already be built at this time and imported in the `FROM projectatomic/atomicapp` line. + +### ./localdir/Nulecule + +This is the `Nulecule` file for Atomic App. The `Nulecule` file is composed of graph and metadata in order to link one or more containers for your application. +```yaml +--- +specversion: 0.0.2 +id: helloapache-app + +metadata: + name: Hello Apache App + appversion: 0.0.1 + description: Atomic app for deploying a really basic Apache HTTP server + +graph: + - 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 + marathon: + - file://artifacts/marathon/helloapache.json +``` + +##### Spec and id information +```yaml +--- +specversion: 0.0.2 +id: helloapache-app +``` + +Here we indicate the specversion of our Atomic App (similar to a `v1` or `v2` of an API) as well as our ID. + +##### Metadata +```yaml +metadata: + name: Hello Apache App + appversion: 0.0.1 + description: Atomic app for deploying a really basic Apache HTTP server +``` + +__Optionally__, a good metadata section will indiciate to a user of your app what it does as well as what version it's on. + +##### Graph + +```yaml +graph: + - 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 + marathon: + - file://artifacts/marathon/helloapache.json +``` + +__Graph__ is the most important section. In here we will indicate all the default parameters as well as all associated artifacts. + +```yaml +params: + - name: image + description: The webserver image + default: centos/httpd +``` +There will likely be many parameters that need to be exposed at deployment. It's best to provide defaults whenever possible. Variable templating is used within artifact files. For example: `$image` within `artifacts/kubernetes/hello-apache-pod.json` becomes `centos/httpd`. + +**NOTE:** Not providing a default variable will require Atomic App to ask the user. Alternatively, an `answers.conf` file can be provided. + +```yaml +artifacts: + docker: + - file://artifacts/docker/hello-apache-pod_run + kubernetes: + - file://artifacts/kubernetes/hello-apache-pod.json + marathon: + - file://artifacts/marathon/helloapache.json +``` +In order to use a particular provider, name as well as a file location required. Each file is a variable-subtituted template of how your Atomic App container is ran. We go more into detail below. + +```yaml +kubernetes: + - file://artifacts/kubernetes/hello-apache-pod.json + - file://artifacts/kubernetes/hello-apache-service.json +``` +Multiple files may also be specified. For example, specifying a pod, service and replication controller for the `kubernetes` provider. + +### ./localdir/artifacts/docker/hello-apache-pod_run +```sh +docker run -d -p $hostport:80 $image +``` +Each artifact uses variable replacement values. For our Docker provider, we substitute the port number with `$hostport` as indicated by our graph in our `Nulecule` file. The same as our `$image` variable. + +### ./localdir/artifacts/kubernetes/hello-apache-pod.json +```json +"image": "$image", +"name": "helloapache", +"ports": [ + { + "containerPort": 80, + "hostPort": $hostport, + "protocol": "TCP" + } +``` + +Similarly, the kubernetes provider uses both `$image` and `$hostport` variables for pod deployment. + +### ./localdir/answers.conf.sample + +`answers.conf.sample` is an answers file generated while fetching. It is a generated ini file that provides parameter answers for non-interactive deployments. + +```ini +[helloapache-app] +image = centos/httpd +hostport = 80 + +[general] +namespace = default +provider = kubernetes +``` + +Default values such as the provider as well as the namespace can be provided. + +In order to use an answers file, simply specify the location of the file when deploying: +```sh +cp answers.conf.sample answers.conf +sudo atomicapp run -a answers.conf . +``` + +### Conclusion + +Now you know how to build your very own first app! After you have created the necessary files go ahead and build/run it! + +```sh +docker build -t myapp . +sudo atomicapp run myapp +``` + +Atomic App is portable and hence you can also deploy regardless of the host: +```sh +# Host 1 +docker build -t myrepo/myapp . +docker push myrepo/myapp + +# Host 2 +docker pull myrepo/myapp +sudo atomicapp run myrepo/myapp +``` + +Although we have yet to cover every `atomicapp` command. Feel free to use `atomicapp [run/fetch/stop] --help` for a list of all options. + +For an extended guide on the `Nulecule` file, read our [extended Nulecule doc](docs/nulecule.md).