github.com/replicatedhq/ship@v0.55.0/pkg/lifecycle/render/helm/fetch.go (about)

     1  package helm
     2  
     3  import (
     4  	"context"
     5  	"path"
     6  
     7  	"github.com/go-kit/kit/log"
     8  	"github.com/go-kit/kit/log/level"
     9  	"github.com/pkg/errors"
    10  	"github.com/replicatedhq/libyaml"
    11  	"github.com/replicatedhq/ship/pkg/api"
    12  	"github.com/replicatedhq/ship/pkg/constants"
    13  	"github.com/replicatedhq/ship/pkg/lifecycle/render/github"
    14  	"github.com/replicatedhq/ship/pkg/lifecycle/render/root"
    15  	"github.com/replicatedhq/ship/pkg/util"
    16  	"github.com/spf13/afero"
    17  )
    18  
    19  // ChartFetcher fetches a chart based on an asset. it returns
    20  // the location that the chart was unpacked to, usually a temporary directory
    21  type ChartFetcher interface {
    22  	FetchChart(
    23  		ctx context.Context,
    24  		asset api.HelmAsset,
    25  		renderRoot string,
    26  		meta api.ReleaseMetadata,
    27  		configGroups []libyaml.ConfigGroup,
    28  		templateContext map[string]interface{},
    29  	) (string, error)
    30  }
    31  
    32  // ClientFetcher is a ChartFetcher that does all the pulling/cloning client side
    33  type ClientFetcher struct {
    34  	Logger       log.Logger
    35  	GitHub       github.Renderer
    36  	FS           afero.Afero
    37  	HelmCommands Commands
    38  }
    39  
    40  func (f *ClientFetcher) FetchChart(
    41  	ctx context.Context,
    42  	asset api.HelmAsset,
    43  	renderRoot string,
    44  	meta api.ReleaseMetadata,
    45  	configGroups []libyaml.ConfigGroup,
    46  	templateContext map[string]interface{},
    47  ) (string, error) {
    48  	debug := log.With(level.Debug(f.Logger), "fetcher", "client")
    49  
    50  	if asset.Local != nil {
    51  		debug.Log("event", "chart.fetch", "source", "local", "root", asset.Local.ChartRoot)
    52  		return asset.Local.ChartRoot, nil
    53  	} else if asset.GitHub != nil {
    54  		checkoutDir, err := f.FS.TempDir(constants.ShipPathInternalTmp, "helmchart")
    55  		if err != nil {
    56  			return "", errors.Wrap(err, "get chart checkout tmpdir")
    57  		}
    58  		asset.GitHub.Dest = checkoutDir
    59  		err = f.GitHub.Execute(
    60  			// just use the base FS, regardless of what renderRoot was specified, we're going to template+remove it
    61  			root.NewRootFS(f.FS, "."),
    62  			*asset.GitHub,
    63  			configGroups,
    64  			renderRoot,
    65  			meta,
    66  			templateContext,
    67  		)(ctx)
    68  
    69  		if err != nil {
    70  			return "", errors.Wrap(err, "fetch github asset")
    71  		}
    72  
    73  		return path.Join(checkoutDir, asset.GitHub.Path), nil
    74  	} else if asset.HelmFetch != nil { // TODO this branch could probably use a unittest
    75  		checkoutDir, err := f.FS.TempDir(constants.ShipPathInternalTmp, "helmchart")
    76  		if err != nil {
    77  			return "", errors.Wrap(err, "get chart checkout tmpdir")
    78  		}
    79  
    80  		err = f.HelmCommands.Init()
    81  		if err != nil {
    82  			return "", errors.Wrap(err, "init helm")
    83  		}
    84  
    85  		err = f.HelmCommands.Fetch(
    86  			asset.HelmFetch.ChartRef,
    87  			asset.HelmFetch.RepoURL,
    88  			asset.HelmFetch.Version,
    89  			checkoutDir,
    90  			constants.InternalTempHelmHome,
    91  		)
    92  		if err != nil {
    93  			return "", errors.Wrap(err, "helm fetch")
    94  		}
    95  
    96  		// find the path that the chart was fetched to
    97  		chartDir, err := util.FindOnlySubdir(checkoutDir, f.FS)
    98  		if err != nil {
    99  			return "", errors.Wrap(err, "failed to find chart dir")
   100  		}
   101  
   102  		return chartDir, nil
   103  	}
   104  
   105  	debug.Log("event", "chart.fetch.fail", "reason", "unsupported")
   106  	return "", errors.New("only 'local', 'github' and 'helm_fetch' chart rendering is supported")
   107  }
   108  
   109  // NewFetcher makes a new chart fetcher
   110  func NewFetcher(
   111  	logger log.Logger,
   112  	github github.Renderer,
   113  	fs afero.Afero,
   114  	helmCommands Commands,
   115  ) ChartFetcher {
   116  	return &ClientFetcher{
   117  		Logger:       logger,
   118  		GitHub:       github,
   119  		FS:           fs,
   120  		HelmCommands: helmCommands,
   121  	}
   122  }