otto/services/parser/README.adoc

2.8 KiB

<html lang="en"> <head> </head>

Otto Parser

The Otto Parser service is responsible for taking a buffer, typically the contents of a .otto file and converting that into the internal representation that Otto uses for a configured pipeline.

Internal Representation

The requirements for the internal representation of a continuous delivery pipeline are as follows:

  • Configuration data must be kept all in one place

  • It should be possible to reason about the runtime resources, and opportunities for re-use ahead of time.

  • Runtime resource allocation must be separable from everything else, in effect, Otto must be able to send off resource allocation requests as soon as possible, with only pointers back to the specific pipeline

  • The path of execution must be numbered and trackable within the system. Other components will need to be able to refer back to the internal representation to determine where in the execution of the pipeline the process is currently.

Example

Below is an example of a simple Otto pipeline, and its corresponding internal representation.

Simple.otto
use {
  stdlib
}

configure {
  slack {
    channel = '#otto'
  }
}

pipeline {
  stages {
    stage {
      name = 'Build'
      runtime {
        docker {
          image = 'ruby:latest'
        }
      }

      cache {
        gems = ['vendor/']
      }

      steps {
        sh 'ruby --version'
      }
    }

    stage {
      name = 'Test'
      runtime {
        from 'Build'
      }
      cache {
        use gems
      }
      steps {
        sh 'env'
      }
    }
  }
}
Note

The description of this internal representation is YAML for the convenience of this documentation, there is zero guarantee that the actual internal representation is stored in this fashion

Simple.otto-internal
ottoVersion: 1
libraries:
  - type: builtin
    ref: stdlib
configuration:
  slack:
    settings:
      channel:
        encrypted: false
        value: '#otto'
runtimes:
  # Most dynamically provisioned runtimes will not have any user-specified
  # named
  - name:
    type: docker
    args:
    image: 'ruby:latest'
# Stages are indexed based on when they are parsed, not necessarily when they
# are expected to execute, which may be in parallel
stages:
  - name: 'Build'
    before:
    after:
    runtime: 0
    steps:
      - type: 'sh'
        args:
          - 'ruby --version'
    # `capture` and `restore` both would support archiving of artifacts and
    # caching of files and directories between the different stages
    capture:
      gems:
        - path: 'gems/'
          type: 'directory'
    restore:
  - name: 'Test'
    before:
    # Reference the stage by index
    after: 0
    runtime: 0
    steps:
      - type: 'sh'
        args:
          - 'env'
    capture:
    restore:
      - gems
</html>