github.com/replicatedhq/ship@v0.55.0/pkg/lifecycle/helmValues/helmValues.go (about)

     1  package helmValues
     2  
     3  import (
     4  	"context"
     5  	"path"
     6  	"path/filepath"
     7  	"time"
     8  
     9  	"github.com/go-kit/kit/log"
    10  	"github.com/go-kit/kit/log/level"
    11  	"github.com/pkg/errors"
    12  	"github.com/replicatedhq/ship/pkg/api"
    13  	"github.com/replicatedhq/ship/pkg/constants"
    14  	"github.com/replicatedhq/ship/pkg/lifecycle"
    15  	"github.com/replicatedhq/ship/pkg/lifecycle/daemon"
    16  	"github.com/replicatedhq/ship/pkg/lifecycle/daemon/daemontypes"
    17  	"github.com/replicatedhq/ship/pkg/state"
    18  	"github.com/spf13/afero"
    19  )
    20  
    21  type helmValues struct {
    22  	Fs           afero.Afero
    23  	Logger       log.Logger
    24  	Daemon       daemontypes.Daemon
    25  	StateManager state.Manager
    26  }
    27  
    28  func NewHelmValues(
    29  	fs afero.Afero,
    30  	logger log.Logger,
    31  	daemon daemontypes.Daemon,
    32  	stateManager state.Manager,
    33  ) lifecycle.HelmValues {
    34  	return &helmValues{
    35  		Fs:           fs,
    36  		Logger:       logger,
    37  		Daemon:       daemon,
    38  		StateManager: stateManager,
    39  	}
    40  }
    41  
    42  type daemonlessHelmValues struct {
    43  	Fs           afero.Afero
    44  	Logger       log.Logger
    45  	StateManager state.Manager
    46  }
    47  
    48  func (d *daemonlessHelmValues) Execute(context.Context, *api.Release, *api.HelmValues) error {
    49  	return d.resolveStateHelmValues()
    50  }
    51  
    52  func (h *helmValues) Execute(ctx context.Context, release *api.Release, step *api.HelmValues) error {
    53  	debug := level.Debug(log.With(h.Logger, "step.type", "helmValues"))
    54  
    55  	daemonExitedChan := h.Daemon.EnsureStarted(ctx, release)
    56  
    57  	debug.Log("event", "readfile.attempt", "dest", path.Join(constants.HelmChartPath, "values.yaml"))
    58  
    59  	currentState, err := h.StateManager.CachedState()
    60  	if err != nil {
    61  		return errors.Wrap(err, "load state")
    62  	}
    63  
    64  	h.Daemon.SetProgress(daemontypes.StringProgress("helmValues", "generating installable application manifests"))
    65  
    66  	currentHelmValues := currentState.CurrentHelmValues()
    67  	if step.Path != "" {
    68  		requestedValues, err := h.Fs.ReadFile(step.Path)
    69  		if err != nil {
    70  			return errors.Wrap(err, "read values")
    71  		}
    72  
    73  		currentHelmValues = string(requestedValues)
    74  	}
    75  
    76  	h.Daemon.PushHelmValuesStep(ctx, daemontypes.HelmValues{
    77  		Values:        currentHelmValues,
    78  		DefaultValues: currentState.CurrentHelmValuesDefaults(),
    79  	}, daemon.HelmValuesActions())
    80  	debug.Log("event", "step.pushed")
    81  
    82  	return h.awaitContinue(ctx, daemonExitedChan)
    83  }
    84  
    85  func (h *helmValues) awaitContinue(ctx context.Context, daemonExitedChan chan error) error {
    86  	debug := level.Debug(log.With(h.Logger, "step.type", "helmValues", "awaitContinue"))
    87  	for {
    88  		select {
    89  		case <-ctx.Done():
    90  			return ctx.Err()
    91  		case err := <-daemonExitedChan:
    92  			if err != nil {
    93  				return err
    94  			}
    95  			return errors.New("daemon exited")
    96  		case <-h.Daemon.MessageConfirmedChan():
    97  			debug.Log("message.confirmed")
    98  			err := h.resolveStateHelmValues()
    99  			if err != nil {
   100  				return errors.Wrap(err, "resolve saved helm values from state.json")
   101  			}
   102  			return nil
   103  		case <-time.After(10 * time.Second):
   104  			debug.Log("waitingFor", "message.confirmed")
   105  		}
   106  	}
   107  }
   108  
   109  func (h *helmValues) resolveStateHelmValues() error {
   110  	return resolveStateHelmValues(h.Logger, h.StateManager, h.Fs)
   111  }
   112  
   113  func resolveStateHelmValues(logger log.Logger, manager state.Manager, fs afero.Afero) error {
   114  	debug := level.Debug(log.With(logger, "step.type", "helmValues", "resolveHelmValues"))
   115  	debug.Log("event", "tryLoadState")
   116  	editState, err := manager.CachedState()
   117  	if err != nil {
   118  		return errors.Wrap(err, "try load state")
   119  	}
   120  	helmValues := editState.CurrentHelmValues()
   121  	if helmValues == "" {
   122  		path := filepath.Join(constants.HelmChartPath, "values.yaml")
   123  		bytes, err := fs.ReadFile(path)
   124  		if err != nil {
   125  			return errors.Wrapf(err, "read helm values from %s", constants.TempHelmValuesPath)
   126  		}
   127  		helmValues = string(bytes)
   128  	}
   129  
   130  	err = fs.MkdirAll(constants.TempHelmValuesPath, 0700)
   131  	if err != nil {
   132  		return errors.Wrapf(err, "make dir %s", constants.TempHelmValuesPath)
   133  	}
   134  	debug.Log("event", "writeTempValuesYaml")
   135  	err = fs.WriteFile(path.Join(constants.TempHelmValuesPath, "values.yaml"), []byte(helmValues), 0644)
   136  	if err != nil {
   137  		return errors.Wrapf(err, "write values.yaml to %s", constants.TempHelmValuesPath)
   138  	}
   139  	return nil
   140  }