Example #1
0
// AddRequestHeaders add a few default headers to req. Currently added: User-
// Agent, X-Wercker-Version, X-Wercker-Git.
func AddRequestHeaders(req *http.Request) {
	userAgent := fmt.Sprintf("wercker %s", util.FullVersion())

	req.Header.Set("User-Agent", userAgent)
	req.Header.Set("X-Wercker-Version", util.Version())
	if util.GitCommit != "" {
		req.Header.Set("X-Wercker-Git", util.GitCommit)
	}
}
Example #2
0
func GetApp() *cli.App {
	// logger.SetLevel(logger.DebugLevel)
	// util.RootLogger().SetLevel("debug")
	// util.RootLogger().Formatter = &logger.JSONFormatter{}

	app := cli.NewApp()
	setupUsageFormatter(app)
	app.Author = "Team wercker"
	app.Name = "wercker"
	app.Usage = "build and deploy from the command line"
	app.Email = "*****@*****.**"
	app.Version = util.FullVersion()
	app.Flags = FlagsFor(GlobalFlagSet)
	app.Commands = []cli.Command{
		buildCommand,
		devCommand,
		checkConfigCommand,
		deployCommand,
		detectCommand,
		// inspectCommand,
		loginCommand,
		logoutCommand,
		pullCommand,
		versionCommand,
		documentCommand(app),
	}
	app.Before = func(ctx *cli.Context) error {
		if ctx.GlobalBool("debug") {
			util.RootLogger().Formatter = &util.VerboseFormatter{}
			util.RootLogger().SetLevel("debug")
		} else {
			util.RootLogger().Formatter = &util.TerseFormatter{}
			util.RootLogger().SetLevel("info")
		}
		if ctx.GlobalBool("journal") {
			util.RootLogger().Hooks.Add(&journalhook.JournalHook{})
			util.RootLogger().Out = ioutil.Discard
		}
		// Register the global signal handler
		util.GlobalSigint().Register(os.Interrupt)
		util.GlobalSigterm().Register(unix.SIGTERM)
		return nil
	}
	return app
}
Example #3
0
// SetupEnvironment does a lot of boilerplate legwork and returns a pipeline,
// box, and session. This is a bit of a long method, but it is pretty much
// the entire "Setup Environment" step.
func (p *Runner) SetupEnvironment(runnerCtx context.Context) (*RunnerShared, error) {
	shared := &RunnerShared{}
	f := &util.Formatter{p.options.GlobalOptions.ShowColors}
	timer := util.NewTimer()

	sr := &StepResult{
		Success:  false,
		Artifact: nil,
		Message:  "",
		ExitCode: 1,
	}

	setupEnvironmentStep := &core.ExternalStep{
		BaseStep: core.NewBaseStep(core.BaseStepOptions{
			Name:    "setup environment",
			Owner:   "wercker",
			Version: util.Version(),
		}),
	}
	finisher := p.StartStep(shared, setupEnvironmentStep, 2)
	defer finisher.Finish(sr)

	if p.options.Verbose {
		p.emitter.Emit(core.Logs, &core.LogsArgs{
			Logs: fmt.Sprintf("Running wercker version: %s\n", util.FullVersion()),
		})
	}

	p.logger.Debugln("Application:", p.options.ApplicationName)

	// Grab our config
	rawConfig, stringConfig, err := p.GetConfig()
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}
	shared.config = rawConfig
	sr.WerckerYamlContents = stringConfig

	// Init the pipeline
	pipeline, err := p.GetPipeline(rawConfig)
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}
	pipeline.InitEnv(p.options.HostEnv)
	shared.pipeline = pipeline

	if p.options.Verbose {
		p.emitter.Emit(core.Logs, &core.LogsArgs{
			Logs: fmt.Sprintf("Using config:\n%s\n", stringConfig),
		})
	}

	// Fetch the box
	timer.Reset()
	box := pipeline.Box()
	_, err = box.Fetch(runnerCtx, pipeline.Env())
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}
	// TODO(termie): dump some logs about the image
	shared.box = box
	if p.options.Verbose {
		p.logger.Printf(f.Success(fmt.Sprintf("Fetched %s", box.GetName()), timer.String()))
	}

	// Fetch the services and add them to the box
	if err := p.AddServices(runnerCtx, pipeline, box); err != nil {
		sr.Message = err.Error()
		return shared, err
	}

	// Start setting up the pipeline dir
	p.logger.Debugln("Copying source to build directory")
	err = p.CopySource()
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}

	// ... and the cache dir
	p.logger.Debugln("Copying cache to build directory")
	err = p.CopyCache()
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}

	p.logger.Debugln("Steps:", len(pipeline.Steps()))

	// Fetch the steps
	steps := pipeline.Steps()
	for _, step := range steps {
		timer.Reset()
		if _, err := step.Fetch(); err != nil {
			sr.Message = err.Error()
			return shared, err
		}
		if p.options.Verbose {
			p.logger.Printf(f.Success("Prepared step", step.Name(), timer.String()))
		}

	}

	// ... and the after steps
	afterSteps := pipeline.AfterSteps()
	for _, step := range afterSteps {
		timer.Reset()
		if _, err := step.Fetch(); err != nil {
			sr.Message = err.Error()
			return shared, err
		}

		if p.options.Verbose {
			p.logger.Printf(f.Success("Prepared step", step.Name(), timer.String()))
		}
	}

	// Boot up our main container, it will run the services
	container, err := box.Run(runnerCtx, pipeline.Env())
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}
	shared.containerID = container.ID

	// Register our signal handler to clean the box up
	// NOTE(termie): we're expecting that this is going to be the last handler
	//               to be run since it calls exit, in the future we might be
	//               able to do something like close the calling context and
	//               short circuit / let the rest of things play out
	boxCleanupHandler := &util.SignalHandler{
		ID: "box-cleanup",
		F: func() bool {
			p.logger.Errorln("Interrupt detected, cleaning up containers and shutting down")
			box.Stop()
			if p.options.ShouldRemove {
				box.Clean()
			}
			os.Exit(1)
			return true
		},
	}
	util.GlobalSigint().Add(boxCleanupHandler)
	util.GlobalSigterm().Add(boxCleanupHandler)

	p.logger.Debugln("Attaching session to base box")
	// Start our session
	sessionCtx, sess, err := p.GetSession(runnerCtx, container.ID)
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}
	shared.sess = sess
	shared.sessionCtx = sessionCtx

	// Some helpful logging
	pipeline.LogEnvironment()

	p.logger.Debugln("Setting up guest (base box)")
	err = pipeline.SetupGuest(sessionCtx, sess)
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}

	err = pipeline.ExportEnvironment(sessionCtx, sess)
	if err != nil {
		sr.Message = err.Error()
		return shared, err
	}

	sr.Message = ""
	sr.Success = true
	sr.ExitCode = 0
	return shared, nil
}