Esempio n. 1
0
func ReleaseList(rw http.ResponseWriter, r *http.Request) *httperr.Error {
	app := mux.Vars(r)["app"]

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

	return RenderJson(rw, releases)
}
Esempio n. 2
0
func SystemReleaseList(rw http.ResponseWriter, r *http.Request) *httperr.Error {
	rack, err := provider.SystemGet()
	if awsError(err) == "ValidationError" {
		return httperr.Errorf(404, "no such stack: %s", rack)
	}
	if err != nil {
		return httperr.Server(err)
	}

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

	return RenderJson(rw, releases)
}
Esempio n. 3
0
// FIXME: Port to provider interface
func (a *App) LatestRelease() (*Release, error) {
	releases, err := provider.ReleaseList(a.Name)
	if err != nil {
		return nil, err
	}

	if len(releases) == 0 {
		return nil, nil
	}

	r := releases[0]

	return &Release{
		Id:       r.Id,
		App:      r.App,
		Build:    r.Build,
		Env:      r.Env,
		Manifest: r.Manifest,
		Created:  r.Created,
	}, nil
}
Esempio n. 4
0
func TestReleaseList(t *testing.T) {
	aws := StubAwsProvider(
		describeStacksCycle,
		releasesQueryCycle,
	)
	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)
	}()

	r, err := provider.ReleaseList("httpd")

	assert.Nil(t, err)

	assert.EqualValues(t, structs.Releases{
		structs.Release{
			Id:       "RVFETUHHKKD",
			App:      "httpd",
			Build:    "BHINCLZYYVN",
			Env:      "foo=bar",
			Manifest: "web:\n  image: httpd\n  ports:\n  - 80:80\n",
			Created:  time.Unix(1459780542, 627770380).UTC(),
		},
		structs.Release{
			Id:       "RFVZFLKVTYO",
			App:      "httpd",
			Build:    "BNOARQMVHUO",
			Env:      "foo=bar",
			Manifest: "web:\n  image: httpd\n  ports:\n  - 80:80\n",
			Created:  time.Unix(1459709199, 166694813).UTC(),
		},
	}, r)
}
Esempio n. 5
0
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
}