Skip to content

Commit

Permalink
Merge pull request #250 from garden-io/fix-examples
Browse files Browse the repository at this point in the history
Fix some examples and docs
  • Loading branch information
eysi09 authored Sep 6, 2018
2 parents 50efa2e + 64de898 commit 36af475
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 154 deletions.
3 changes: 2 additions & 1 deletion docs/examples/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Examples

The source code for the examples in this section can be found in our Github [examples repository](https://github.com/garden-io/garden-examples/).
The source code for the examples in this section can be found in our Github repository under the
[examples directory](https://github.com/garden-io/garden/examples/).

* [Simple Project](./simple-project.md)
6 changes: 3 additions & 3 deletions docs/examples/simple-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ This tutorial assumes that you have already have a running [installation of Gard

## Clone the example repo

The code for this tutorial can be found on Github in our [examples repo](https://github.com/garden-io/garden-examples). We'll use the [simple-project-start](https://github.com/garden-io/garden-examples/simple-project-start) example and work our way from there. The complete version is under [simple-project](https://github.com/garden-io/garden-examples/simple-project).
The code for this tutorial can be found on Github in our [examples repo](https://github.com/garden-io/garden/examples). We'll use the [simple-project-start](https://github.com/garden-io/garden/examples/simple-project-start) example and work our way from there. The complete version is under [simple-project](https://github.com/garden-io/garden/examples/simple-project).

First, let's clone the examples repo, change into the directory, and take a look inside:
```sh
$ git clone https://github.com/garden-io/garden-examples.git
$ cd garden-examples/simple-project-start
$ git clone https://github.com/garden-io/garden/examples.git
$ cd garden/examples/simple-project-start
$ tree .
.
└── services
Expand Down
229 changes: 93 additions & 136 deletions docs/guides/configuration.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,66 @@
## Configuration
# Configuration

Garden is configured via `garden.yml` configuration files.

The [project-wide](#project-configuration) `garden.yml` file should be located in the top-level directory of the
project's Git
repository.
project's Git repository.

In addition, each of the project's [modules](../guides/glossary.md#module)' `garden.yml` should be located in that module's
top-level
directory.

Currently, Garden projects assume that all their modules are rooted in subdirectories of the same Git repository.
In a future release, this mono-repo structure will be made optional.
In addition, each of the project's [modules](../guides/glossary.md#module)' `garden.yml` should be located in that
module's top-level directory.

To get started, create a `garden.yml` file in the top-level directory of your repository, and a `garden.yml` file
in the top-level directory of each of the modules you'd like do define for your project.

To decide how to split your project up into modules, it's useful to consider what parts of it are built as a single
step, and what the dependency relationships are between your build steps. For example, each container and each
serverless function should be represented by its own module

Then, you can configure each module's endpoints via the [`services` directive](#services) in its `garden.yml`.
serverless function should be represented by its own module.

Below, we'll be using examples from the
[hello-world example project](https://github.com/garden-io/garden/tree/528b141717f718ebe304d2ebde87b85d0c6c5e50/examples/hello-world).
[hello-world example project](https://github.com/garden-io/garden/tree/master/examples/hello-world), which touches
on many of the things you're likely to want to configure in a project.

## Project Configuration

We'll start by looking at the top-level [project configuration file](https://github.com/garden-io/garden/blob/master/examples/hello-world/garden.yml).

### Project Configuration
[Github link](https://github.com/garden-io/garden/blob/528b141717f718ebe304d2ebde87b85d0c6c5e50/examples/hello-world/garden.yml)
```yaml
# examples/hello-world/garden.yml
project:
name: hello-world
global:
providers:
- name: container
- name: npm-package
environmentDefaults:
variables:
my-variable: hello-variable
environments:
- name: local
providers:
- name: local-kubernetes
- name: local-google-cloud-functions
- name: dev
providers:
- name: google-app-engine
- name: google-cloud-functions
default-project: garden-hello-world
- name: openfaas
```
The project-wide `garden.yml` defines the project's name, the default providers used for each
[plugin](../guides/glossary.md#plugin) the project requires (via the `global` directive), and
[environment](../guides/glossary.md#environment)-specific provider overrides as is appropriate for each of the project's
configured environments (`local` and `dev` under the `environments` directive above).
The project-wide `garden.yml` defines the project's name, the default configuration used for each
[environment](../guides/glossary.md#environment) (via the `environmentDefaults` directive), and
environment-specific provider configuration. The above only configures a `local` environment, but you could add
further environments, such as a remote Kubernetes environment.

Here, project-wide configuration variables can also be specified (global, and/or environment-specific). These are
then available for interpolation in any string scalar value in any module's `garden.yml`.

For example, assuming the above project configuration, `"foo-${variables.my-variable}-bar"` would evaluate to
`"foo-hello-variable-bar"` when used as a scalar string value in a module's `garden.yml`.
For example, assuming the above project configuration, `"foo-${variables.my-variable}-bar"` would evaluate to
`"foo-hello-variable-bar"` when used as a scalar string value in a module's `garden.yml`.

## Module Configuration

### Module Configuration
Below, we'll use the module configurations of `hello-function` and `hello-container` from the
[hello-world example project](https://github.com/garden-io/garden/tree/528b141717f718ebe304d2ebde87b85d0c6c5e50/examples/hello-world)
[hello-world example project](https://github.com/garden-io/garden/tree/master/examples/hello-world)
as examples to illustrate some of the primary module-level configuration options.

The following is a snippet from [`hello-function`'s module config](#hello-function-module-configuration):
The following is a snippet from [`hello-container`'s module config](#hello-function-module-configuration):

```yaml
module:
description: Hello world serverless function
type: google-cloud-function
name: hello-function
name: hello-container
type: container
description: Hello world container service
...
build:
dependencies:
Expand All @@ -79,40 +70,66 @@ module:
target: libraries/hello-npm-package/
```

#### name
The first lines you'll find in all module configurations, and describe the module at a high level.

The second part, the `build` key, demonstrates how Garden can serve as a build framework, managing build dependencies
and even copying files between modules as they are built.

Below is a run-down of the individual configuration keys, and what they represent:

### name

The module's name, used e.g. when referring to it from another module's configuration as a
[build dependency](#build-configuration), or when building specific modules with `garden build`.

Note that module names must be unique within a given project. An error will be thrown in any Garden CLI command if two
modules use the same name.

#### type
A [module](../guides/glossary.md#module)'s `type` specifies its plugin type. Garden interprets this according to the
active environment's configured provider for the specified plugin type.
### type

A [module](../guides/glossary.md#module)'s `type` specifies what kind of module this is, which will control how the
module's code gets built, tested, deployed etc. The module types are defined by _plugins_. The built-in plug-ins
include `container` and `generic` (which basically provides a way to run commands locally).

The example above is a `container` module, and the `hello-function` module is an `openfaas` module
(which is one of many ways to run functions-as-a-service on Kubernetes).

In this particular project, the `container` module type is deployed by the `local-kubernetes` plugin, and the
`openfaas` module is built and deployed by the corresponding `openfaas` plugin.

For example,
[`hello-container`](#hello-container-module-configuration)'s `type` is set to `container`, which the
[project configuration](#project-configuration) above interprets as `local-kubernetes` (a Docker container managed
via a local Kubernetes installation), assuming that the `local` environment is being used.
### build

#### build
A module's build configuration is specified via the `build` directive.

Under `build`, the `command` subdirective sets the CLI command run during builds. A module's build command is executed
Here, the `build.command` subdirective sets the CLI command run during builds. A module's build command is executed
with its working directory set to a copy of the module's top-level directory, located at
`[project-root]/.garden/build/[module-name]`. This internal directory is referred to as the module's
[build directory](../guides/glossary.md#build-directory).

The `.garden` directory should not be modified by users, since this may lead to unexpected errors when the Garden CLI
tools are used in the project.

##### Build Dependencies
The `dependencies` subdirective lists the module's build dependencies. `name` is the required module's name, and
`copy` indicates what files/folders, if any, should be copied from the required module's build directory to the
module in question after the required module is built (`source`), and where they should be copied (`target).
The `build.dependencies` subdirective lists the module's build dependencies, which need to be built ahead of this module.
`name` is the required module's name. In many cases you only need to declare the build dependency name. For example,
you simply need to build one container before another because it's used as a base image.

In other cases, you may actually need files to be copied from one built module to another.
The `copy` key indicates what files/folders, if any, should be copied from the required module's build directory to the
module in question after the required module is built (`source`), and where they should be copied (`target`).

In the above example, we copy the entire contents of `hello-npm-package`'s build directory, after it has been built,
into the `libraries/hello-npm-package/` in the `hello-container` build directory, _before the container is built_.

## Services

A module may contain zero or more _services_. Services are deployed when running `garden deploy` or `garden dev` as
part of your runtime stack.

How services are configured will depend on the module type. An `openfaas` module always contains a single service. A
`container` module can contain any number of services (or none at all, if it's just used as a base image, for example).

#### Services
The following is a snippet from [`hello-container's`'s module config](#hello-container-module-configuration):

```yaml
module:
description: Hello world container service
Expand All @@ -134,34 +151,22 @@ module:
- hello-function
...
```
The `services` directive defines the services exposed by the module.

##### name
The service's name, used e.g. when referring to it as a dependency of another service, or when deploying
specific services with `garden deploy`. Service names must be unique across all modules within a given project. An
error will be thrown in any Garden CLI command if two services use the same name.

##### command
The CLI command to be executed (after the module is built) to make the service's endpoints available.

##### ports
Names each port exposed by the service.
Here the `services` directive defines the services exposed by the module. We only have one service in this example,
but you might for example add another service, for example a background worker, that is started using a different
`command`.

##### endpoints
Enumerates the functional endpoints exposed by the service, defining the relative path and port to associate with
each of them.
For more details on how to configure services in a `container` module, please refer to the
[config reference](../reference/config.md).

##### healthcheck
Defines the endpoint used to query the service's availability.
## Tests

##### dependencies
Lists the names of the services that must be deployed before the service in question (the `hello-container` service, in
this case) is deployed.
Each module can define one or more test suites. How these tests are specified, much like services, depends on the
individual module type. However the concepts are most often the same; you specify one or more test suites, how to
execute them, and in some cases which services need to be running for the tests to run successfully.

##### tests
A list of named test configurations for the module.
For an example, here is another snippet from the `hello-container` module configuration:

Following is another snippet from [`hello-container`'s module config](#hello-container-module-configuration):
```yaml
module:
description: Hello world container service
Expand All @@ -175,70 +180,22 @@ module:
dependencies:
- hello-function
```
Test groups can be run by `name` via `garden test`. `command` is the CLI command to run the specified tests, and
`dependencies` lists (by name) the services (if any) that must be deployed before the test group in question is run.

#### Functions (experimental)
For modules defining serverless functions, the `functions` directive specifies the names and entry points of the
functions the module exposes. Note that serverless functionality is still experimental and under active development.
Here we define two types of tests. First are unit tests, which can be run on their own without any dependencies. The
framework only needs to know which command to run, and the rest is handled by the module's code itself.

This section is currently only included to clarify the `functions` directive in
[`hello-function`'s module config](#hello-function-module-configuration), since it's used as an example here.
The other test suite, `integ`, leverages the Garden framework's ability to manage runtime dependencies for tests. In
this case, the integ test suite needs the `hello-function` service to be running for the tests to execute.

### Examples
This allows you write tests that actually call out to other services, rather than having to mock or stub those services
in your tests.

#### hello-function Module Configuration
[Github link](https://github.com/garden-io/garden/blob/528b141717f718ebe304d2ebde87b85d0c6c5e50/examples/hello-world/services/hello-function/garden.yml)
````yaml
# examples/hello-world/services/hello-function/garden.yml
module:
description: Hello world serverless function
name: hello-function
type: google-cloud-function
functions:
- name: hello-function
entrypoint: helloFunction
tests:
- name: unit
command: [npm, test]
build:
dependencies:
- name: hello-npm-package
copy:
- source: "./"
target: libraries/hello-npm-package/
````
Tests can be run via `garden test`, as well as `garden dev`.

#### hello-container Module Configuration
[Github link](https://github.com/garden-io/garden/blob/528b141717f718ebe304d2ebde87b85d0c6c5e50/examples/hello-world/services/hello-container/garden.yml)
```yaml
# examples/hello-world/services/hello-container/garden.yml
module:
description: Hello world container service
type: container
services:
- name: hello-container
command: [npm, start]
ports:
- name: http
containerPort: 8080
endpoints:
- path: /hello
port: http
healthCheck:
httpGet:
path: /_ah/health
port: http
dependencies:
- hello-function
build:
dependencies:
- hello-npm-package
tests:
- name: unit
command: [npm, test]
- name: integ
command: [npm, run, integ]
dependencies:
- hello-function
```
## Next steps

We highly recommend browsing through the [examples directory](https://github.com/garden-io/garden/tree/master/examples)
to see different examples of how projects and modules can be configured.

Also be sure to look at the configuration [reference](../reference/config.md) for more details on each of the available
configuration keys.
6 changes: 3 additions & 3 deletions docs/introduction/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,15 @@ To later upgrade to the newest version, run `npm install -g -U garden-cli`.

## Using the CLI

With the CLI installed, we can now try out a few commands using the [hello-world](https://github.com/garden-io/garden-examples/tree/master/simple-project) project from our Github [examples repository](https://github.com/garden-io/garden-examples). The example consists of a a couple of simple services.
With the CLI installed, we can now try out a few commands using the [hello-world](https://github.com/garden-io/garden/examples/tree/master/simple-project) project from our Github [examples repository](https://github.com/garden-io/garden/examples). The example consists of a a couple of simple services.

_Note: check if Kubernetes is running with `kubectl version`. You should see both a `Client Version` and a `Server Version` in the response. If not, please start it up before proceeding._

Clone the repo and change into the `hello-world` directory:

```sh
$ git clone https://github.com/garden-io/garden-examples.git
$ cd garden-examples/hello-world
$ git clone https://github.com/garden-io/garden/examples.git
$ cd garden/examples/hello-world
```

First, let's check the environment status by running the following from the project root:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"os"
"fmt"
"net/http"
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"os"
"fmt"
"net/http"
)
Expand Down
2 changes: 1 addition & 1 deletion garden-cli/src/plugins/openfaas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ function getK8sProvider(ctx: PluginContext): KubernetesProvider {
}

function getServicePath(service: OpenFaasService) {
return join("function", service.name)
return join("/", "function", service.name)
}

async function getInternalGatewayUrl(ctx: PluginContext) {
Expand Down
Loading

0 comments on commit 36af475

Please sign in to comment.