示例#1
0
文件: builds.go 项目: cleblanc87/rack
func BuildList(rw http.ResponseWriter, r *http.Request) *httperr.Error {
	app := mux.Vars(r)["app"]

	builds, err := provider.BuildList(app)
	if awsError(err) == "ValidationError" {
		return httperr.Errorf(404, "no such app: %s", app)
	}
	if err != nil {
		return httperr.Server(err)
	}

	return RenderJson(rw, builds)
}
示例#2
0
func TestBuildList(t *testing.T) {
	aws := StubAwsProvider(
		describeStacksCycle,
		buildsQueryCycle,

		build1GetObjectCycle,
		build2GetObjectCycle,
	)
	defer aws.Close()

	defer func() {
		//TODO: remove: as we arent updating all tests we need to set current provider back to a
		//clean default one (I miss rspec before)
		provider.CurrentProvider = new(provider.TestProviderRunner)
	}()

	b, err := provider.BuildList("httpd")

	assert.Nil(t, err)
	assert.EqualValues(t, structs.Builds{
		structs.Build{
			Id:       "BHINCLZYYVN",
			App:      "httpd",
			Logs:     "RUNNING: docker pull httpd",
			Manifest: "web:\n  image: httpd\n  ports:\n  - 80:80\n",
			Release:  "RVFETUHHKKD",
			Status:   "complete",
			Started:  time.Unix(1459780456, 178278576).UTC(),
			Ended:    time.Unix(1459780542, 440881687).UTC(),
		},
		structs.Build{
			Id:       "BNOARQMVHUO",
			App:      "httpd",
			Logs:     "RUNNING: docker pull httpd",
			Manifest: "web:\n  image: httpd\n  ports:\n  - 80:80\n",
			Release:  "RFVZFLKVTYO",
			Status:   "complete",
			Started:  time.Unix(1459709087, 472025215).UTC(),
			Ended:    time.Unix(1459709198, 984281955).UTC(),
		},
	}, b)
}
示例#3
0
文件: app.go 项目: cleblanc87/rack
func (a *App) Cleanup() error {
	err := cleanupBucket(a.Outputs["Settings"])

	if err != nil {
		return err
	}

	// FIXME: BuildList and ReleaseList only lists and cleans up the last 20 builds/releases
	// FIXME: Should the delete calls happen in a goroutine?
	builds, err := provider.BuildList(a.Name)
	if err != nil {
		return err
	}

	for _, build := range builds {
		provider.BuildDelete(a.Name, build.Id)
	}

	releases, err := provider.ReleaseList(a.Name)
	if err != nil {
		return err
	}

	for _, release := range releases {
		provider.ReleaseDelete(a.Name, release.Id)
	}

	// monitor and stack deletion state for up to 10 minutes
	// retry once if DELETE_FAILED to automate around transient errors
	// send delete success event only when stack is gone
	shouldRetry := true

	for i := 0; i < 60; i++ {
		res, err := CloudFormation().DescribeStacks(&cloudformation.DescribeStacksInput{
			StackName: aws.String(a.StackName()),
		})

		// return when stack is not found indicating successful delete
		if ae, ok := err.(awserr.Error); ok {
			if ae.Code() == "ValidationError" {
				helpers.TrackEvent("kernel-app-delete-success", nil)
				// Last ditch effort to remove the empty bucket CF leaves behind.
				_, err := S3().DeleteBucket(&s3.DeleteBucketInput{Bucket: aws.String(a.Outputs["Settings"])})
				if err != nil {
					fmt.Printf("error: %s\n", err)
				}
				return nil
			}
		}

		if err == nil && len(res.Stacks) == 1 && shouldRetry {
			// if delete failed, issue one more delete stack and return
			s := res.Stacks[0]
			if *s.StackStatus == "DELETE_FAILED" {
				helpers.TrackEvent("kernel-app-delete-retry", nil)

				_, err := CloudFormation().DeleteStack(&cloudformation.DeleteStackInput{StackName: aws.String(a.StackName())})

				if err != nil {
					helpers.TrackEvent("kernel-app-delete-retry-error", nil)
				} else {
					shouldRetry = false
				}
			}
		}

		time.Sleep(10 * time.Second)
	}

	return nil
}