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 }