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

     1  package unfork
     2  
     3  import (
     4  	"context"
     5  	"strings"
     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/ship/pkg/api"
    11  	"github.com/replicatedhq/ship/pkg/lifecycle"
    12  	"github.com/replicatedhq/ship/pkg/patch"
    13  	"github.com/replicatedhq/ship/pkg/state"
    14  	"github.com/replicatedhq/ship/pkg/util"
    15  	"github.com/spf13/afero"
    16  	yaml "gopkg.in/yaml.v3"
    17  )
    18  
    19  type Unforker struct {
    20  	Logger  log.Logger
    21  	FS      afero.Afero
    22  	State   state.Manager
    23  	Patcher patch.Patcher
    24  }
    25  
    26  func NewDaemonlessUnforker(logger log.Logger, fs afero.Afero, state state.Manager, patcher patch.Patcher) lifecycle.Unforker {
    27  	return &Unforker{
    28  		Logger:  logger,
    29  		FS:      fs,
    30  		State:   state,
    31  		Patcher: patcher,
    32  	}
    33  }
    34  
    35  func (l *Unforker) Execute(ctx context.Context, release *api.Release, step api.Unfork) error {
    36  	debug := level.Debug(log.With(l.Logger, "struct", "daemonless.unforker", "method", "execute"))
    37  
    38  	debug.Log("event", "upstream.map")
    39  	upstreamMap := map[util.MinimalK8sYaml]string{}
    40  	if err := l.mapUpstream(upstreamMap, step.UpstreamBase); err != nil {
    41  		return errors.Wrap(err, "map upstream")
    42  	}
    43  
    44  	debug.Log("event", "state.loaded")
    45  	fs, err := l.getPotentiallyChrootedFs(release)
    46  	if err != nil {
    47  		debug.Log("event", "getFs.fail")
    48  		return errors.Wrapf(err, "get base fs")
    49  	}
    50  
    51  	debug.Log("event", "mkdir", "dir", step.OverlayPath())
    52  	err = l.FS.MkdirAll(step.OverlayPath(), 0777)
    53  	if err != nil {
    54  		debug.Log("event", "mkdir.fail", "dir", step.OverlayPath())
    55  		return errors.Wrapf(err, "make dir %s", step.OverlayPath())
    56  	}
    57  
    58  	// this isn't in the right place, but it works until we figure out the right workflow...
    59  	kustomizeState, err := l.generatePatchesAndExcludeBases(fs, step, upstreamMap)
    60  	if err != nil {
    61  		debug.Log("event", "generate.patches.fail", "err", err)
    62  		return errors.Wrapf(err, "generate patches")
    63  	}
    64  
    65  	debug.Log("event", "write.base.kustomization.yaml")
    66  	if err := l.writeBase(step); err != nil {
    67  		return errors.Wrap(err, "write base kustomization")
    68  	}
    69  
    70  	shipOverlay := kustomizeState.Ship()
    71  
    72  	relativePatchPaths, err := l.writePatches(fs, shipOverlay, step.OverlayPath())
    73  	if err != nil {
    74  		return err
    75  	}
    76  
    77  	relativeResourcePaths, err := l.writeResources(fs, shipOverlay, step.OverlayPath())
    78  	if err != nil {
    79  		return err
    80  	}
    81  
    82  	err = l.writeOverlay(step, relativePatchPaths, relativeResourcePaths)
    83  	if err != nil {
    84  		return errors.Wrap(err, "write overlay")
    85  	}
    86  
    87  	if step.Dest != "" {
    88  		debug.Log("event", "unfork.build", "dest", step.Dest)
    89  		built, err := l.unforkBuild(step.OverlayPath())
    90  		if err != nil {
    91  			return errors.Wrap(err, "build overlay")
    92  		}
    93  
    94  		if err := l.writePostKustomizeFiles(step, built); err != nil {
    95  			return errors.Wrapf(err, "write kustomized and post processed yaml at %s", step.Dest)
    96  		}
    97  	}
    98  
    99  	return nil
   100  }
   101  
   102  func (l *Unforker) unforkBuild(kustomizePath string) ([]util.PostKustomizeFile, error) {
   103  	debug := level.Debug(log.With(l.Logger, "struct", "daemonless.unforker", "method", "unforkBuild"))
   104  
   105  	builtYAML, err := l.Patcher.RunKustomize(kustomizePath)
   106  	if err != nil {
   107  		return nil, errors.Wrap(err, "run kustomize")
   108  	}
   109  
   110  	files := strings.Split(string(builtYAML), "\n---\n")
   111  	postKustomizeFiles := make([]util.PostKustomizeFile, 0)
   112  	for idx, file := range files {
   113  		var fullYaml interface{}
   114  
   115  		debug.Log("event", "unmarshal part of rendered")
   116  		if err := yaml.Unmarshal([]byte(file), &fullYaml); err != nil {
   117  			return postKustomizeFiles, errors.Wrap(err, "unmarshal part of rendered")
   118  		}
   119  
   120  		debug.Log("event", "unmarshal part of rendered to minimal")
   121  		minimal := util.MinimalK8sYaml{}
   122  		if err := yaml.Unmarshal([]byte(file), &minimal); err != nil {
   123  			return postKustomizeFiles, errors.Wrap(err, "unmarshal part of rendered to minimal")
   124  		}
   125  
   126  		postKustomizeFiles = append(postKustomizeFiles, util.PostKustomizeFile{
   127  			Order:   idx,
   128  			Minimal: minimal,
   129  			Full:    fullYaml,
   130  		})
   131  	}
   132  
   133  	return postKustomizeFiles, nil
   134  }