github.com/leowmjw/otto@v0.2.1-0.20160126165905-6400716cf085/builtin/app/python/app.go (about) 1 package pythonapp 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "strings" 7 8 "github.com/hashicorp/otto/app" 9 "github.com/hashicorp/otto/appfile" 10 pythonSP "github.com/hashicorp/otto/builtin/scriptpack/python" 11 stdSP "github.com/hashicorp/otto/builtin/scriptpack/stdlib" 12 "github.com/hashicorp/otto/helper/bindata" 13 "github.com/hashicorp/otto/helper/compile" 14 "github.com/hashicorp/otto/helper/oneline" 15 "github.com/hashicorp/otto/helper/packer" 16 "github.com/hashicorp/otto/helper/schema" 17 "github.com/hashicorp/otto/helper/terraform" 18 "github.com/hashicorp/otto/helper/vagrant" 19 "github.com/hashicorp/otto/scriptpack" 20 ) 21 22 //go:generate go-bindata -pkg=pythonapp -nomemcopy -nometadata ./data/... 23 24 // App is an implementation of app.App 25 type App struct{} 26 27 func (a *App) Meta() (*app.Meta, error) { 28 return Meta, nil 29 } 30 31 func (a *App) Implicit(ctx *app.Context) (*appfile.File, error) { 32 return nil, nil 33 } 34 35 func (a *App) Compile(ctx *app.Context) (*app.CompileResult, error) { 36 var opts compile.AppOptions 37 custom := &customizations{Opts: &opts} 38 opts = compile.AppOptions{ 39 Ctx: ctx, 40 Bindata: &bindata.Data{ 41 Asset: Asset, 42 AssetDir: AssetDir, 43 Context: map[string]interface{}{}, 44 }, 45 ScriptPacks: []*scriptpack.ScriptPack{ 46 &stdSP.ScriptPack, 47 &pythonSP.ScriptPack, 48 }, 49 Customization: (&compile.Customization{ 50 Callback: custom.process, 51 Schema: map[string]*schema.FieldSchema{ 52 "python_version": &schema.FieldSchema{ 53 Type: schema.TypeString, 54 Default: "2.7", 55 Description: "Python version to install", 56 }, 57 "python_entrypoint": &schema.FieldSchema{ 58 Type: schema.TypeString, 59 Default: fmt.Sprintf("%s:app", ctx.Appfile.Application.Name), 60 Description: "WSGI entry point", 61 }, 62 }, 63 }).Merge(compile.VagrantCustomizations(&opts)), 64 } 65 66 return compile.App(&opts) 67 } 68 69 func (a *App) Build(ctx *app.Context) error { 70 return packer.Build(ctx, &packer.BuildOptions{ 71 InfraOutputMap: map[string]string{ 72 "region": "aws_region", 73 }, 74 }) 75 } 76 77 func (a *App) Deploy(ctx *app.Context) error { 78 return terraform.Deploy(&terraform.DeployOptions{ 79 InfraOutputMap: map[string]string{ 80 "region": "aws_region", 81 "subnet-private": "private_subnet_id", 82 "subnet-public": "public_subnet_id", 83 }, 84 }).Route(ctx) 85 } 86 87 func (a *App) Dev(ctx *app.Context) error { 88 // Read the go version, since we use that for our layer 89 version, err := oneline.Read(filepath.Join(ctx.Dir, "dev", "python_version")) 90 if err != nil { 91 return err 92 } 93 94 // Setup layers 95 layered, err := vagrant.DevLayered(ctx, []*vagrant.Layer{ 96 &vagrant.Layer{ 97 ID: fmt.Sprintf("python%s", version), 98 Vagrantfile: filepath.Join(ctx.Dir, "dev", "layer-base", "Vagrantfile"), 99 }, 100 }) 101 if err != nil { 102 return err 103 } 104 105 // Build the actual development environment 106 return vagrant.Dev(&vagrant.DevOptions{ 107 Instructions: strings.TrimSpace(devInstructions), 108 Layer: layered, 109 }).Route(ctx) 110 } 111 112 func (a *App) DevDep(dst, src *app.Context) (*app.DevDep, error) { 113 return vagrant.DevDep(dst, src, &vagrant.DevDepOptions{}) 114 } 115 116 const devInstructions = ` 117 A development environment has been created for writing a generic 118 Python-based app. 119 120 Python is pre-installed. To work on your project, edit files locally on your 121 own machine. The file changes will be synced to the development environment. 122 123 When you're ready to build your project, run 'otto dev ssh' to enter 124 the development environment. You'll be placed directly into the working 125 directory with a virtualenv setup where you can run 'pip' and 'python' 126 as you normally would. 127 128 You can access any running web application using the IP above. 129 `