func (o *InstallOptions) runInstall(ctx context.Context) (*release.Release, error) {
	log.SetFlags(0)          
	log.SetOutput(o.ErrOut)  
	cp, err := o.client.ChartPathOptions.LocateChart(o.ChartName, o.settings)
	if err != nil {
		return nil, err
	}
	chart, err := loader.Load(cp)
	if err != nil {
		return nil, err
	}
	if err := checkIfInstallable(chart); err != nil {
		return nil, err
	}
	if chart.Metadata.Deprecated {
		log.Printf("This chart is deprecated")
	}
	p := getter.All(o.settings)
	chartValues, err := o.valueOpts.MergeValues(p)
	if err != nil {
		return nil, err
	}
	o.client.DryRun = true                   
	o.client.ClientOnly = true               
	chartValues[installCRDsFlagName] = true  
	dryRunResult, err := o.client.Run(chart, chartValues)
	if err != nil {
		return nil, err
	}
	if o.DryRun {
		return dryRunResult, nil
	}
	if err := o.cfg.Init(o.settings.RESTClientGetter(), o.settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
		return nil, err
	}
	resources, err := helm.ParseMultiDocumentYAML(dryRunResult.Manifest, o.cfg.KubeClient)
	if err != nil {
		return nil, err
	}
	crds := helm.FilterCrdResources(resources)
	if len(crds) == 0 {
		return nil, fmt.Errorf("Found no CRDs in provided cert-manager chart.")
	}
	originalCRDs, err := helm.FetchResources(crds, o.cfg.KubeClient)
	if err != nil {
		return nil, err
	}
	if len(originalCRDs) > 0 {
		return nil, fmt.Errorf("Found existing installed cert-manager CRDs! Cannot continue with installation.")
	}
	if err := helm.CreateCRDs(crds, o.cfg); err != nil {
		return nil, err
	}
	o.client.DryRun = false      
	o.client.ClientOnly = false  
	o.client.Wait = o.Wait  
	o.client.Atomic = o.Wait
	o.client.DisableHooks = !o.Wait
	chartValues[installCRDsFlagName] = false  
	return o.client.Run(chart, chartValues)
}
The overall strategy is to install the CRDs first, and not as part of a Helm
release, and then to install a Helm release without the CRDs.  This is to
ensure that CRDs are not removed by a subsequent helm uninstall or by a
future cmctl uninstall. We want the removal of CRDs to only be performed by
an administrator who understands that the consequences of removing CRDs will
be the garbage collection of all the related CRs in the cluster.  We first
do a dry-run install of the chart (effectively helm template
--validate=false) to render the CRDs from the CRD templates in the Chart.
The ClientOnly option is required, otherwise Helm will return an error in
case the CRDs are already installed in the cluster.  We then extract the
CRDs from the resulting dry-run manifests and install those first.  Finally,
we perform a helm install to install the remaining non-CRD resources and
wait for those to be "Ready".
This creates a Helm "release" artifact in a Secret in the target namespace, which contains
a record of all the resources installed by Helm (except the CRDs).
package install
import (
	"context"
	"fmt"
	"io"
	"log"
	"os"
	"strings"
	"time"
	"github.com/spf13/cobra"
	"helm.sh/helm/v3/pkg/action"
	"helm.sh/helm/v3/pkg/chart"
	"helm.sh/helm/v3/pkg/chart/loader"
	"helm.sh/helm/v3/pkg/cli"
	"helm.sh/helm/v3/pkg/cli/values"
	"helm.sh/helm/v3/pkg/getter"
	"helm.sh/helm/v3/pkg/release"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	"github.com/jetstack/cert-manager/cmd/ctl/pkg/build"
	"github.com/jetstack/cert-manager/cmd/ctl/pkg/install/helm"
)
type InstallOptions struct {
	settings  *cli.EnvSettings
	client    *action.Install
	cfg       *action.Configuration
	valueOpts *values.Options
	ChartName string
	DryRun    bool
	Wait      bool
	genericclioptions.IOStreams
}
const (
	installCRDsFlagName         = "installCRDs"
	defaultCertManagerNamespace = "cert-manager"
)
func installDesc() string {
	return build.WithTemplate(`This command installs cert-manager. It uses the Helm libraries to do so.
The latest published cert-manager chart in the "https://charts.jetstack.io" repo is used.
Most of the features supported by 'helm install' are also supported by this command.
In addition, his command will always correctly install the required CRD resources.
Some example uses:
	$ {{.BuildName}} x install
or
	$ {{.BuildName}} x install -n new-cert-manager
or
	$ {{.BuildName}} x install --version v1.4.0
or
	$ {{.BuildName}} x install --set prometheus.enabled=false
To override values in the cert-manager chart, use either the '--values' flag and
pass in a file or use the '--set' flag and pass configuration from the command line.
`)
}
func NewCmdInstall(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
	settings := cli.New()
	cfg := new(action.Configuration)
	options := &InstallOptions{
		settings:  settings,
		cfg:       cfg,
		client:    action.NewInstall(cfg),
		valueOpts: &values.Options{},
		IOStreams: ioStreams,
	}
	cmd := &cobra.Command{
		Use:   "install",
		Short: "Install cert-manager",
		Long:  installDesc(),
		RunE: func(cmd *cobra.Command, args []string) error {
			options.client.Namespace = settings.Namespace()
			rel, err := options.runInstall(ctx)
			if err != nil {
				return err
			}
			if options.DryRun {
				fmt.Fprintf(ioStreams.Out, "%s", rel.Manifest)
				return nil
			}
			printReleaseSummary(ioStreams.Out, rel)
			return nil
		},
		SilenceUsage:  true,
		SilenceErrors: true,
	}
	settings.AddFlags(cmd.Flags())
	cmd.Flag("namespace").DefValue = defaultCertManagerNamespace
	addInstallUninstallFlags(cmd.Flags(), &options.client.Timeout, &options.Wait)
	addInstallFlags(cmd.Flags(), options.client)
	addValueOptionsFlags(cmd.Flags(), options.valueOpts)
	addChartPathOptionsFlags(cmd.Flags(), &options.client.ChartPathOptions)
	cmd.Flags().BoolVar(&options.client.CreateNamespace, "create-namespace", true, "Create the release namespace if not present")
	cmd.Flags().MarkHidden("create-namespace")
	cmd.Flags().StringVar(&options.ChartName, "chart-name", "cert-manager", "Name of the chart to install")
	cmd.Flags().MarkHidden("chart-name")
	cmd.Flags().BoolVar(&options.DryRun, "dry-run", false, "Simulate install and output manifest")
	return cmd
}