func (a *App) Dev(ctx *app.Context) error { var layered *vagrant.Layered // We only setup a layered environment if we've recompiled since // version 0. If we're still at version 0 then we have to use the // non-layered dev environment. if ctx.CompileResult.Version > 0 { // Read the go version, since we use that for our layer version, err := oneline.Read(filepath.Join(ctx.Dir, "dev", "node_version")) if err != nil { return err } // Setup layers layered, err = vagrant.DevLayered(ctx, []*vagrant.Layer{ &vagrant.Layer{ ID: fmt.Sprintf("node%s", version), Vagrantfile: filepath.Join(ctx.Dir, "dev", "layer-base", "Vagrantfile"), }, }) if err != nil { return err } } // Build the actual development environment return vagrant.Dev(&vagrant.DevOptions{ Instructions: strings.TrimSpace(devInstructions), Layer: layered, }).Route(ctx) }
// LoadCompiled loads and verifies a compiled Appfile (*Compiled) from // disk. func LoadCompiled(dir string) (*Compiled, error) { // Check the version vsnStr, err := oneline.Read(filepath.Join(dir, CompileVersionFilename)) if err != nil { return nil, err } vsn, err := strconv.ParseInt(vsnStr, 0, 0) if err != nil { return nil, err } // If the version is too new, then we can't handle it if vsn > CompileVersion { return nil, fmt.Errorf( "The Appfile for this enviroment was compiled with a newer version\n" + "of Otto. Otto can't load this environment. You can recompile this\n" + "environment to this version of Otto with `otto compile`.") } f, err := os.Open(filepath.Join(dir, CompileFilename)) if err != nil { return nil, err } defer f.Close() var c Compiled dec := json.NewDecoder(f) if err := dec.Decode(&c); err != nil { return nil, err } return &c, nil }
func (a *App) Build(ctx *app.Context) error { // Determine if we set a Packer path. path := filepath.Join(ctx.Dir, "build", "packer_path") if _, err := os.Stat(path); err != nil { if os.IsNotExist(err) { return errors.New(strings.TrimSpace(errPackerNotSet)) } return err } // Read the actual Packer dir packerPath, err := oneline.Read(path) if err != nil { return fmt.Errorf( "Error reading the Packer template path: %s\n\n"+ "An Otto recompile with `otto compile` usually fixes this.", err) } return packer.Build(ctx, &packer.BuildOptions{ Dir: filepath.Dir(packerPath), TemplatePath: packerPath, }) }
func (a *App) Deploy(ctx *app.Context) error { // Determine if we set a Terraform path. If we didn't, then // tell the user we can't deploy. path := filepath.Join(ctx.Dir, "deploy", "terraform_path") if _, err := os.Stat(path); err != nil { if os.IsNotExist(err) { return errors.New(strings.TrimSpace(errTerraformNotSet)) } return err } // Read the actual TF dir tfdir, err := oneline.Read(path) if err != nil { return fmt.Errorf( "Error reading the Terraform module directory: %s\n\n"+ "An Otto recompile with `otto compile` usually fixes this.", err) } // Determine if we set a Packer path. If we didn't, we disable // the build loading for deploys. disableBuild := true path = filepath.Join(ctx.Dir, "build", "packer_path") if _, err := os.Stat(path); err == nil { disableBuild = false } // But if we did, then deploy using Terraform return terraform.Deploy(&terraform.DeployOptions{ Dir: tfdir, DisableBuild: disableBuild, }).Route(ctx) }
// appFoundations compiles the app-specific foundation files. func appFoundations(opts *AppOptions) error { // Setup the bindata for rendering dataCopy := Data data := &dataCopy data.Context = make(map[string]interface{}) for k, v := range opts.Bindata.Context { data.Context[k] = v } // Go through each foundation and setup the layers log.Printf("[INFO] compile: looking for foundation layers for dev") for i, dir := range opts.Ctx.FoundationDirs { devDir := filepath.Join(dir, "app-dev") log.Printf("[DEBUG] compile: checking foundation dir: %s", devDir) _, err := os.Stat(filepath.Join(devDir, "layer.sh")) if err != nil { // If the file doesn't exist then this foundation just // doesn't have a layer. Not a big deal. if os.IsNotExist(err) { log.Printf("[DEBUG] compile: dir %s has no layers", devDir) continue } // The error is something else, return it... return err } log.Printf("[DEBUG] compile: dir %s has a layer!", devDir) // We have a layer! Read the ID. id, err := oneline.Read(filepath.Join(devDir, "layer.id")) if err != nil { return err } // Setup the data for this render data.Context["foundation_id"] = id data.Context["foundation_dir"] = devDir // Create the directory where this will be stored renderDir := filepath.Join( opts.Ctx.Dir, "foundation-layers", fmt.Sprintf("%d-%s", i, id)) if err := os.MkdirAll(renderDir, 0755); err != nil { return err } // Render our standard template for a foundation layer err = data.RenderAsset( filepath.Join(renderDir, "Vagrantfile"), "data/internal/foundation-layer.Vagrantfile.tpl") if err != nil { return err } } return nil }
// loadID loads the ID for this File. func (appF *File) loadID() error { hasID, err := appF.hasID() if err != nil { return err } if !hasID { appF.ID = "" return nil } path := filepath.Join(filepath.Dir(appF.Path), IDFile) uuid, err := oneline.Read(path) if err != nil { return err } appF.ID = uuid return nil }
func detectRubyVersionFile(dir string) (result string, err error) { path := filepath.Join(dir, ".ruby-version") // Verify the .ruby-version exists if _, err = os.Stat(path); err != nil { if os.IsNotExist(err) { log.Printf("[DEBUG] ruby: .ruby-version not found, will not detect Ruby version this way") err = nil } return } log.Printf("[DEBUG] ruby: .ruby-version found! Attempting to detect Ruby version") // Read the first line of the file result, err = oneline.Read(path) log.Printf("[DEBUG] ruby: .ruby-version detected Ruby: %q", result) return }
func (a *App) Dev(ctx *app.Context) error { // Determine if we have a Vagrant path set... instructions := devInstructionsCustom path := filepath.Join(ctx.Dir, "dev", "vagrant_path") if _, err := os.Stat(path); err != nil { if !os.IsNotExist(err) { return err } path = "" } if path != "" { var err error path, err = oneline.Read(path) if err != nil { return fmt.Errorf( "Error reading the Vagrant directory: %s\n\n"+ "An Otto recompile with `otto compile` usually fixes this.", err) } } if path == "" { // Determine if we have our own Vagrantfile path = filepath.Join(ctx.Dir, "dev", "Vagrantfile") if _, err := os.Stat(path); err != nil { if os.IsNotExist(err) { return errors.New(strings.TrimSpace(errVagrantNotSet)) } return err } instructions = devInstructionsDevDep } return vagrant.Dev(&vagrant.DevOptions{ Dir: filepath.Dir(path), Instructions: strings.TrimSpace(instructions), }).Route(ctx) }
// IP retrieves the IP address. // // If it is cached, it will renew and use that address. If it isn't cached, // then it will grab a new IP, cache that, and use that. func (db *CachedDB) IP() (net.IP, error) { log.Printf("[DEBUG] reading IP, cache path: %s", db.CachePath) // Try to read the cached version _, err := os.Stat(db.CachePath) if err == nil { raw, err := oneline.Read(db.CachePath) if err != nil { return nil, err } ip := net.ParseIP(raw) if ip != nil { log.Printf("[DEBUG] read ip from cache: %s", ip) db.DB.Renew(ip) return ip, nil } } // Make sure the directory to our cache path exists if err := os.MkdirAll(filepath.Dir(db.CachePath), 0755); err != nil { return nil, err } // No cached version. log.Printf("[DEBUG] no ip cache found, getting new IP") ip, err := db.DB.Next() if err != nil { return nil, err } contents := fmt.Sprintf(strings.TrimSpace(cacheContents)+"\n", ip.String()) err = ioutil.WriteFile(db.CachePath, []byte(contents), 0644) if err != nil { db.DB.Release(ip) return nil, err } log.Printf("[DEBUG] new IP cached: %s", ip) return ip, nil }
func (a *App) Dev(ctx *app.Context) error { // Read the go version, since we use that for our layer version, err := oneline.Read(filepath.Join(ctx.Dir, "dev", "python_version")) if err != nil { return err } // Setup layers layered, err := vagrant.DevLayered(ctx, []*vagrant.Layer{ &vagrant.Layer{ ID: fmt.Sprintf("python%s", version), Vagrantfile: filepath.Join(ctx.Dir, "dev", "layer-base", "Vagrantfile"), }, }) if err != nil { return err } // Build the actual development environment return vagrant.Dev(&vagrant.DevOptions{ Instructions: strings.TrimSpace(devInstructions), Layer: layered, }).Route(ctx) }