github.com/dahs81/otto@v0.2.1-0.20160126165905-6400716cf085/app/app.go (about)

     1  // app contains the interfaces and structures for application type
     2  // implementations for Otto. Applications are the components that
     3  // know how to dev, build, and deploy a certain kind of application such
     4  // as Rails, PHP, etc.
     5  //
     6  // All app implementations are built specific to a certain 3-tuple:
     7  // (app type, infra type, infra flavor). For example:
     8  // (rails, aws, vpc-public-private). The app implementation then only
     9  // needs to know how to satisfy that specific 3-tuple.
    10  //
    11  // When building app plugins, it is possible for that plugin to support
    12  // multiple matrix elements, but each implementation of the interface
    13  // is expeced to only implement one.
    14  package app
    15  
    16  import (
    17  	"github.com/hashicorp/otto/appfile"
    18  	"github.com/hashicorp/otto/appfile/detect"
    19  	"github.com/hashicorp/otto/context"
    20  	"github.com/hashicorp/otto/foundation"
    21  	"github.com/hashicorp/otto/ui"
    22  )
    23  
    24  // App is the interface that must be implemented by each
    25  // (app type, infra type, infra flavor) 3-tuple.
    26  type App interface {
    27  	// Meta returns the metadata about this App implementation.
    28  	Meta() (*Meta, error)
    29  
    30  	// Implicit returns implicit configurations for an Appfile that is
    31  	// using this type. This is called after this app type is detected
    32  	// to be used, and allows the app implementation to setup defaults.
    33  	//
    34  	// The App implementation can then define implicit dependencies and
    35  	// things like that based on the environment.
    36  	//
    37  	// The Context argument for this function call will be very sparse.
    38  	// Only Appfile and UI will be set. Everythign else should be considered
    39  	// unusable.
    40  	Implicit(*Context) (*appfile.File, error)
    41  
    42  	// Compile is called to compile the files that are used to manage
    43  	// this application.
    44  	Compile(*Context) (*CompileResult, error)
    45  
    46  	// Build is called to build the deployable artifact for this
    47  	// application.
    48  	Build(*Context) error
    49  
    50  	// Deploy is called to deploy this application. The existence of
    51  	// a prior build artifact is confirmed before this is called.
    52  	Deploy(*Context) error
    53  
    54  	// Dev should manage a development environment for this app
    55  	// type. This is called for the local, mutable dev environment
    56  	// where this application is the main thing under development.
    57  	Dev(*Context) error
    58  
    59  	// DevDep is called when this app is an upstream dependency
    60  	// of another application that is being developed. This app should
    61  	// build itself for development, and configure the Vagrantfile so
    62  	// that this dependency starts properly on boot.
    63  	//
    64  	// DevDep is given two contexts. The first is the destination
    65  	// app (the one being developed), and the second is the source
    66  	// app (this one that is an upstream dep).
    67  	//
    68  	// The results of this call are cached to speed up development
    69  	// of the destination app until there is a change, which is detected
    70  	// based on VCS.
    71  	//
    72  	// The resulting DevDep can be nil if nothing needs to be done that
    73  	// is part of the DevDep structure. Any DevDepFragments from the
    74  	// compilation will still be used, of course.
    75  	DevDep(dst *Context, src *Context) (*DevDep, error)
    76  }
    77  
    78  // Meta is metadata about an app implementation.
    79  type Meta struct {
    80  	// Tuples returns the tuples that this app implementation supports.
    81  	Tuples TupleSlice
    82  
    83  	// Detectors are the detectors that exist for this app type.
    84  	Detectors []*detect.Detector
    85  }
    86  
    87  // Context is the context for operations on applications. Some of the
    88  // fields in this struct are only available for certain operations.
    89  type Context struct {
    90  	context.Shared
    91  
    92  	// CompileResult is the result of the compilation. This is set on
    93  	// all calls except Compile to be the data from the compilation. This
    94  	// can be used to check compile versions, for example.
    95  	CompileResult *CompileResult
    96  
    97  	// Action is the sub-action to take when being executed.
    98  	//
    99  	// ActionArgs is the list of arguments for this action.
   100  	//
   101  	// Both of these fields will only be set for the Execute call.
   102  	Action     string
   103  	ActionArgs []string
   104  
   105  	// Dir is the directory that the compilation is allowed to write to
   106  	// for persistant storage of data that is available during task
   107  	// execution. For tasks, this will be the directory that compilation
   108  	// wrote to. Whenever a compilation is done, this directory is
   109  	// cleared. Data that should be persistant across compilations should
   110  	// be stored in the directory service.
   111  	Dir string
   112  
   113  	// CacheDir is the directory where data can be cached. This data
   114  	// will persist across compiles of the same version of an Appfile.
   115  	//
   116  	// GlobalCacheDir is a directory that is shared across multiple
   117  	// Otto runs. It can be accessed by any app type and any Otto run. App
   118  	// types should be _extremely_ careful to use multi-process locking
   119  	// to prevent races. Additionally, you must be absolutely certain to
   120  	// have a cleanup process for this directory for your own files.
   121  	//
   122  	// The App implementation should function under the assumption that
   123  	// this cache directory can be cleared at any time between runs.
   124  	CacheDir string
   125  
   126  	// LocalDir is the directory where data local to this single Appfile
   127  	// will be stored; it isn't cleared for compilation.
   128  	//
   129  	// GlobalDir is the directory where data global to Otto will be stored.
   130  	// It is never automatically cleared so any usage of this directory
   131  	// must have a cleanup mechanism in some way.
   132  	LocalDir  string
   133  	GlobalDir string
   134  
   135  	// Tuple is the Tuple that identifies this application. This can be
   136  	// used so that an implementatin of App can work with multiple tuple
   137  	// types.
   138  	Tuple Tuple
   139  
   140  	// Application is the application configuration itself from the appfile.
   141  	Application *appfile.Application
   142  
   143  	// DevDepFragments will be populated with the list of dev dep
   144  	// Vagrantfile fragment paths. This will only be available in the Compile
   145  	// call.
   146  	DevDepFragments []string
   147  
   148  	// DevIPAddress is a local IP address in the private address space
   149  	// that can be used for a development environment. Otto core
   150  	// does its best to ensure this is unused.
   151  	//
   152  	// This is only available if this app is the root application being
   153  	// developed (dependencies don't get an IP).
   154  	DevIPAddress string
   155  }
   156  
   157  // RouteName implements the router.Context interface so we can use Router
   158  func (c *Context) RouteName() string {
   159  	return c.Action
   160  }
   161  
   162  // RouteArgs implements the router.Context interface so we can use Router
   163  func (c *Context) RouteArgs() []string {
   164  	return c.ActionArgs
   165  }
   166  
   167  // UI implements router.Context so we can use this in router.Router
   168  func (c *Context) UI() ui.Ui {
   169  	return c.Ui
   170  }
   171  
   172  // CompileResult is the structure containing compilation result values.
   173  type CompileResult struct {
   174  	// Version is the version of the compiled result. This is purely metadata:
   175  	// the app itself should use this to detect certain behaviors on run.
   176  	Version uint32 `json:"version"`
   177  
   178  	// FoundationConfig is the configuration for the various foundational
   179  	// elements of Otto.
   180  	FoundationConfig foundation.Config `json:"foundation_config"`
   181  
   182  	// DevDepFragmentPath is the path to the Vagrantfile fragment that
   183  	// should be added to other Vagrantfiles when this application is
   184  	// used as a dependency.
   185  	DevDepFragmentPath string `json:"dev_dep_fragment_path"`
   186  
   187  	// FoundationResults are the compilation results of the foundations.
   188  	//
   189  	// This is populated by Otto core and any set value here will be ignored.
   190  	FoundationResults map[string]*foundation.CompileResult `json:"foundation_results"`
   191  }