Beispiel #1
0
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)
}
Beispiel #2
0
// 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
}
Beispiel #3
0
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,
	})
}
Beispiel #4
0
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)
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
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
}
Beispiel #8
0
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)
}
Beispiel #9
0
// 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
}
Beispiel #10
0
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)
}