// GetRelease fetches a single release.
//
// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release
507422
func (s *RepositoriesService) GetRelease(ctx context.Context, owner, repo string, id int64) (*RepositoryRelease, *Response, error) {
	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
	return s.getSingleRelease(ctx, u)
}
826510
func getRelease() (string, error) {
	cmd := exec.Command("system_profiler", "SPSoftwareDataType")
	osName, err := cmd.Output()
	if err != nil {
		return "", err
	}

	var release string
	data := strings.Split(string(osName), "\n")
	for _, line := range data {
		if strings.Contains(line, "Kernel Version") {
			// It has the format like '      Kernel Version: Darwin 14.5.0'
			content := strings.SplitN(line, ":", 2)
			if len(content) != 2 {
				return "", fmt.Errorf("Kernel Version is invalid")
			}

			prettyNames, err := shellwords.Parse(content[1])
			if err != nil {
				return "", fmt.Errorf("Kernel Version is invalid: %s", err.Error())
			}

			if len(prettyNames) != 2 {
				return "", fmt.Errorf("Kernel Version needs to be 'Darwin x.x.x' ")
			}
			release = prettyNames[1]
		}
	}

	return release, nil
}
1314792
func (s *ReleaseServer) GetReleaseStatus(c ctx.Context, req *services.GetReleaseStatusRequest) (*services.GetReleaseStatusResponse, error) {
	if err := validateReleaseName(req.Name); err != nil {
		s.Log("getStatus: Release name is invalid: %s", req.Name)
		return nil, err
	}

	var rel *release.Release

	if req.Version <= 0 {
		var err error
		rel, err = s.env.Releases.Last(req.Name)
		if err != nil {
			return nil, fmt.Errorf("getting deployed release %q: %s", req.Name, err)
		}
	} else {
		var err error
		if rel, err = s.env.Releases.Get(req.Name, req.Version); err != nil {
			return nil, fmt.Errorf("getting release '%s' (v%d): %s", req.Name, req.Version, err)
		}
	}

	if rel.Info == nil {
		return nil, errors.New("release info is missing")
	}
	if rel.Chart == nil {
		return nil, errors.New("release chart is missing")
	}

	sc := rel.Info.Status.Code
	statusResp := &services.GetReleaseStatusResponse{
		Name:      rel.Name,
		Namespace: rel.Namespace,
		Info:      rel.Info,
	}

	// Ok, we got the status of the release as we had jotted down, now we need to match the
	// manifest we stashed away with reality from the cluster.
	resp, err := s.ReleaseModule.Status(rel, req, s.env)
	if sc == release.Status_DELETED || sc == release.Status_FAILED {
		// Skip errors if this is already deleted or failed.
		return statusResp, nil
	} else if err != nil {
		s.Log("warning: Get for %s failed: %v", rel.Name, err)
		return nil, err
	}
	rel.Info.Status.Resources = resp
	return statusResp, nil
}
910100
func (r *RepositoryRelease) GetPrerelease() bool {
	if r == nil || r.Prerelease == nil {
		return false
	}
	return *r.Prerelease
}
565921
func (v *VersionClient) Get(ctx context.Context) (*apitypes.Version, error) {
	version := apitypes.Version{}
	err := v.client.RoundTrip(ctx, "GET", "/version", nil, nil, &version)
	return &version, err
}
796854
func GetRelease(repoID int64, tagName string) (*Release, error) {
	isExist, err := IsReleaseExist(repoID, tagName)
	if err != nil {
		return nil, err
	} else if !isExist {
		return nil, ErrReleaseNotExist{0, tagName}
	}

	r := &Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)}
	if _, err = x.Get(r); err != nil {
		return nil, fmt.Errorf("Get: %v", err)
	}

	return r, r.LoadAttributes()
}
662075
func (r *Release) GetUpgradableRelease(name string) (*hapi_release.Release, error) {
	rls, err := r.HelmClient.ReleaseContent(name)
	if err != nil {
		if strings.Contains(err.Error(), "not found") {
			return nil, nil
		}
		return nil, err
	}

	release := rls.GetRelease()
	status := release.GetInfo().GetStatus()

	switch status.GetCode() {
	case hapi_release.Status_DEPLOYED:
		return release, nil
	case hapi_release.Status_FAILED:
		return nil, fmt.Errorf("release requires a rollback before it can be upgraded (%s)", status.GetCode().String())
	case hapi_release.Status_PENDING_INSTALL,
	     hapi_release.Status_PENDING_UPGRADE,
	     hapi_release.Status_PENDING_ROLLBACK:
		return nil, fmt.Errorf("operation pending for release (%s)", status.GetCode().String())
	default:
		return nil, fmt.Errorf("current state prevents it from being upgraded (%s)", status.GetCode().String())
	}
}
119583
func WithRelease(release string) func(*client) {
	return func(c *client) {
		c.c.SetRelease(release)
	}
}
1372348
func SortReleases(rels []*Release) {
	sorter := &ReleaseSorter{releases: rels}
	sort.Sort(sorter)
}
967010
func (s *ReleaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
	res := &services.InstallReleaseResponse{Release: r}
	manifestDoc := []byte(r.Manifest)

	if req.DryRun {
		s.Log("dry run for %s", r.Name)

		if !req.DisableCrdHook && hasCRDHook(r.Hooks) {
			s.Log("validation skipped because CRD hook is present")
			res.Release.Info.Description = "Validation skipped because CRDs are not installed"
			return res, nil
		}

		// Here's the problem with dry runs and CRDs: We can't install a CRD
		// during a dry run, which means it cannot be validated.
		if err := validateManifest(s.env.KubeClient, req.Namespace, manifestDoc); err != nil {
			return res, err
		}

		res.Release.Info.Description = "Dry run complete"
		return res, nil
	}

	// crd-install hooks
	if !req.DisableHooks && !req.DisableCrdHook {
		if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.CRDInstall, req.Timeout); err != nil {
			fmt.Printf("Finished installing CRD: %s", err)
			return res, err
		}
	} else {
		s.Log("CRD install hooks disabled for %s", req.Name)
	}

	// Because the CRDs are installed, they are used for validation during this step.
	if err := validateManifest(s.env.KubeClient, req.Namespace, manifestDoc); err != nil {
		return res, fmt.Errorf("validation failed: %s", err)
	}

	// pre-install hooks
	if !req.DisableHooks {
		if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PreInstall, req.Timeout); err != nil {
			return res, err
		}
	} else {
		s.Log("install hooks disabled for %s", req.Name)
	}

	switch h, err := s.env.Releases.History(req.Name); {
	// if this is a replace operation, append to the release history
	case req.ReuseName && err == nil && len(h) >= 1:
		s.Log("name reuse for %s requested, replacing release", req.Name)
		// get latest release revision
		relutil.Reverse(h, relutil.SortByRevision)

		// old release
		old := h[0]

		// update old release status
		old.Info.Status.Code = release.Status_SUPERSEDED
		s.recordRelease(old, true)

		// update new release with next revision number
		// so as to append to the old release's history
		r.Version = old.Version + 1
		updateReq := &services.UpdateReleaseRequest{
			Wait:     req.Wait,
			Recreate: false,
			Timeout:  req.Timeout,
		}
		s.recordRelease(r, false)
		if err := s.ReleaseModule.Update(old, r, updateReq, s.env); err != nil {
			msg := fmt.Sprintf("Release replace %q failed: %s", r.Name, err)
			s.Log("warning: %s", msg)
			old.Info.Status.Code = release.Status_SUPERSEDED
			r.Info.Status.Code = release.Status_FAILED
			r.Info.Description = msg
			s.recordRelease(old, true)
			s.recordRelease(r, true)
			return res, err
		}

	default:
		// nothing to replace, create as normal
		// regular manifests
		s.recordRelease(r, false)
		if err := s.ReleaseModule.Create(r, req, s.env); err != nil {
			msg := fmt.Sprintf("Release %q failed: %s", r.Name, err)
			s.Log("warning: %s", msg)
			r.Info.Status.Code = release.Status_FAILED
			r.Info.Description = msg
			s.recordRelease(r, true)
			return res, fmt.Errorf("release %s failed: %s", r.Name, err)
		}
	}

	// post-install hooks
	if !req.DisableHooks {
		if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PostInstall, req.Timeout); err != nil {
			msg := fmt.Sprintf("Release %q failed post-install: %s", r.Name, err)
			s.Log("warning: %s", msg)
			r.Info.Status.Code = release.Status_FAILED
			r.Info.Description = msg
			s.recordRelease(r, true)
			return res, err
		}
	}

	r.Info.Status.Code = release.Status_DEPLOYED
	if req.Description == "" {
		r.Info.Description = "Install complete"
	} else {
		r.Info.Description = req.Description
	}
	// This is a tricky case. The release has been created, but the result
	// cannot be recorded. The truest thing to tell the user is that the
	// release was created. However, the user will not be able to do anything
	// further with this release.
	//
	// One possible strategy would be to do a timed retry to see if we can get
	// this stored in the future.
	s.recordRelease(r, true)

	return res, nil
}
1294816
func (c *FakeFluxHelmReleases) Get(name string, options v1.GetOptions) (result *v1alpha2.FluxHelmRelease, err error) {
	obj, err := c.Fake.
		Invokes(testing.NewGetAction(fluxhelmreleasesResource, c.ns, name), &v1alpha2.FluxHelmRelease{})

	if obj == nil {
		return nil, err
	}
	return obj.(*v1alpha2.FluxHelmRelease), err
}
584169
func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*release.Release, error) {
	if req.Chart == nil {
		return nil, errMissingChart
	}

	name, err := s.uniqName(req.Name, req.ReuseName)
	if err != nil {
		return nil, err
	}

	caps, err := capabilities(s.clientset.Discovery())
	if err != nil {
		return nil, err
	}

	revision := 1
	ts := timeconv.Now()
	options := chartutil.ReleaseOptions{
		Name:      name,
		Time:      ts,
		Namespace: req.Namespace,
		Revision:  revision,
		IsInstall: true,
	}
	valuesToRender, err := chartutil.ToRenderValuesCaps(req.Chart, req.Values, options, caps)
	if err != nil {
		return nil, err
	}

	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender, req.SubNotes, caps.APIVersions)
	if err != nil {
		// Return a release with partial data so that client can show debugging
		// information.
		rel := &release.Release{
			Name:      name,
			Namespace: req.Namespace,
			Chart:     req.Chart,
			Config:    req.Values,
			Info: &release.Info{
				FirstDeployed: ts,
				LastDeployed:  ts,
				Status:        &release.Status{Code: release.Status_UNKNOWN},
				Description:   fmt.Sprintf("Install failed: %s", err),
			},
			Version: 0,
		}
		if manifestDoc != nil {
			rel.Manifest = manifestDoc.String()
		}
		return rel, err
	}

	// Store a release.
	rel := &release.Release{
		Name:      name,
		Namespace: req.Namespace,
		Chart:     req.Chart,
		Config:    req.Values,
		Info: &release.Info{
			FirstDeployed: ts,
			LastDeployed:  ts,
			Status:        &release.Status{Code: release.Status_PENDING_INSTALL},
			Description:   "Initial install underway", // Will be overwritten.
		},
		Manifest: manifestDoc.String(),
		Hooks:    hooks,
		Version:  int32(revision),
	}
	if len(notesTxt) > 0 {
		rel.Info.Status.Notes = notesTxt
	}

	return rel, nil
}
1130805
func GetReleaseVersions() ([]*Version, error) {
	versions, err := GetVersions()
	if err != nil {
		return nil, err
	}
	var output []*Version
	for _, version := range versions {
		if version.Version.String() != version.FullVersion {
			continue
		}
		output = append(output, version)
	}
	return output, nil
}
1134832
func GetHumanVersion() string {
	version := Version
	if GitDescribe != "" {
		version = GitDescribe
	}

	release := VersionPrerelease
	if GitDescribe == "" && release == "" {
		release = "dev"
	}

	if release != "" {
		if !strings.HasSuffix(version, "-"+release) {
			// if we tagged a prerelease version then the release is in the version already
			version += fmt.Sprintf("-%s", release)
		}
		if GitCommit != "" {
			version += fmt.Sprintf(" (%s)", GitCommit)
		}
	}

	// Strip off any single quotes added by the git information.
	return strings.Replace(version, "'", "", -1)
}
220512
func (h *Client) RollbackRelease(rlsName string, opts ...RollbackOption) (*rls.RollbackReleaseResponse, error) {
	reqOpts := h.opts
	for _, opt := range opts {
		opt(&reqOpts)
	}
	req := &reqOpts.rollbackReq
	req.Recreate = reqOpts.recreate
	req.Force = reqOpts.force
	req.DisableHooks = reqOpts.disableHooks
	req.DryRun = reqOpts.dryRun
	req.Name = rlsName
	ctx := NewContext()

	if reqOpts.before != nil {
		if err := reqOpts.before(ctx, req); err != nil {
			return nil, err
		}
	}
	return h.rollback(ctx, req)
}
1274899
func (s *ReleaseServer) GetVersion(c ctx.Context, req *services.GetVersionRequest) (*services.GetVersionResponse, error) {
	v := version.GetVersionProto()
	return &services.GetVersionResponse{Version: v}, nil
}
637857
func GetDraftReleasesByRepoID(repoID int64) ([]*Release, error) {
	releases := make([]*Release, 0)
	return releases, x.Where("repo_id = ?", repoID).And("is_draft = ?", true).Find(&releases)
}