Skip to content

Commit

Permalink
i think... its solid?
Browse files Browse the repository at this point in the history
Signed-off-by: schristoff <28318173+schristoff@users.noreply.github.com>
  • Loading branch information
schristoff committed Dec 4, 2023
1 parent 97764e4 commit 049e220
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 56 deletions.
1 change: 0 additions & 1 deletion pkg/cnab/config-adapter/testdata/myenv-depsv2.bundle.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@
"app": {
"bundle": "localhost:5000/myapp:v1.2.3",
"sharing": {
"mode": false,
"group": {}
},
"parameters": {
Expand Down
2 changes: 2 additions & 0 deletions pkg/cnab/extended_bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ func (b *ExtendedBundle) BuildPrerequisiteInstallationName(installation string,
}

// this is all copied v2 stuff
// todo(schristoff): in the future, we should clean this up

// ResolveVersion returns the bundle name, its version and any error.
func (b *ExtendedBundle) ResolveVersionv2(name string, dep v2.Dependency) (OCIReference, error) {
ref, err := ParseOCIReference(dep.Bundle)
Expand Down
87 changes: 62 additions & 25 deletions pkg/porter/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ func (e *dependencyExecutioner) Execute(ctx context.Context) error {

// executeDependency the requested action against all the dependencies
for _, dep := range e.deps {
if !e.sharedActionResolver(ctx, dep) {
return nil
}
err := e.executeDependency(ctx, dep)
if err != nil {
return err
Expand All @@ -123,13 +126,47 @@ func (e *dependencyExecutioner) PrepareRootActionArguments(ctx context.Context)
// This creates what goes in /cnab/app/dependencies/DEP.NAME
for _, dep := range e.deps {
// Copy the dependency bundle.json
e.checkSharedOutputs(ctx, dep)
target := runtime.GetDependencyDefinitionPath(dep.DependencyLock.Alias)
args.Files[target] = string(dep.cnabFileContents)
}

return args, nil
}

func (e *dependencyExecutioner) checkSharedOutputs(ctx context.Context, dep *queuedDependency) {
if !e.sharedActionResolver(ctx, dep) && e.parentAction.GetAction() == "install" {
e.getActionArgs(ctx, dep)
}
}

// sharedActionResolver tries to localize if v2, and shared deps
// then what actions should we take based off labels/action type/state
// true means continue, false means stop
func (e *dependencyExecutioner) sharedActionResolver(ctx context.Context, dep *queuedDependency) bool {
depInstallation, err := e.Installations.GetInstallation(ctx, e.parentOpts.Namespace, dep.Alias)
if err != nil {
if errors.Is(err, storage.ErrNotFound{}) {
return true
}
}
e.depArgs.Installation = depInstallation

//We're real, let's check if this is in the installation the parent
// is referencing
if dep.SharingGroup == depInstallation.Labels["sh.porter.SharingGroup"] {
if e.parentAction.GetAction() == "install" {
return false
}
if e.parentAction.GetAction() == "upgrade" {
return true
}
if e.parentAction.GetAction() == "uninstall" {
return false
}
}
return true
}

func (e *dependencyExecutioner) identifyDependencies(ctx context.Context) error {
ctx, span := tracing.StartSpan(ctx)
defer span.EndSpan()
Expand Down Expand Up @@ -303,7 +340,9 @@ func (e *dependencyExecutioner) executeDependency(ctx context.Context, dep *queu
}
}

if err = e.getActionArgs(ctx, dep, depInstallation); err != nil {
e.depArgs.Installation = depInstallation

if err = e.getActionArgs(ctx, dep); err != nil {
return err
}

Expand All @@ -315,8 +354,7 @@ func (e *dependencyExecutioner) executeDependency(ctx context.Context, dep *queu
}

// runDependencyv2 will see if the child dependency is already installed
// if so, it will not install the dependency, but rather share the new parent
// to the child
// and if so, use sharingmode && group to resolve what to do
func (e *dependencyExecutioner) runDependencyv2(ctx context.Context, dep *queuedDependency) error {
depInstallation, err := e.Installations.GetInstallation(ctx, e.parentOpts.Namespace, dep.Alias)
if err != nil {
Expand All @@ -334,18 +372,29 @@ func (e *dependencyExecutioner) runDependencyv2(ctx context.Context, dep *queued
return err
}
}
//We save the installation
e.depArgs.Installation = depInstallation

// Installed: Return
// Uninstalled: Error (delete or else)
// Upgrade: Unsupported
// Invoke: At your own risk
//todo(schristoff): this is kind of icky, can be it less so?
if dep.SharingGroup == depInstallation.Labels["sh.porter.SharingGroup"] {
//todo(schristoff): should we just make a new one if uninstalled?
// but then what should it's name be.
if !depInstallation.Uninstalled {
if depInstallation.IsInstalled() {

action := e.parentAction.GetAction()
if action == "upgrade" || action == "uninstall" {
return nil
}
}
if depInstallation.Uninstalled {
return fmt.Errorf("error executing dependency, dependency must be in installed status or deleted, %s is in status %s", dep.Alias, depInstallation.Status)
}

}

//todo(schristoff): PEP003 Find a better place to put this.
// if dep.SharingMode && e.parentAction.GetAction()
if err = e.getActionArgs(ctx, dep, depInstallation); err != nil {
if err = e.getActionArgs(ctx, dep); err != nil {
return err
}

Expand All @@ -357,15 +406,15 @@ func (e *dependencyExecutioner) runDependencyv2(ctx context.Context, dep *queued
}

func (e *dependencyExecutioner) getActionArgs(ctx context.Context,
dep *queuedDependency, depInstallation storage.Installation) error {
finalParams, err := e.porter.finalizeParameters(ctx, depInstallation, dep.BundleReference.Definition, e.parentArgs.Action, dep.Parameters)
dep *queuedDependency) error {
finalParams, err := e.porter.finalizeParameters(ctx, e.depArgs.Installation, dep.BundleReference.Definition, e.parentArgs.Action, dep.Parameters)
if err != nil {
return fmt.Errorf("error resolving parameters for dependency %s: %w", dep.Alias, err)
}
e.depArgs = cnabprovider.ActionArguments{
BundleReference: dep.BundleReference,
Action: e.parentArgs.Action,
Installation: depInstallation,
Installation: e.depArgs.Installation,
Driver: e.parentArgs.Driver,
AllowDockerHostAccess: e.parentOpts.AllowDockerHostAccess,
Params: finalParams,
Expand All @@ -382,21 +431,9 @@ func (e *dependencyExecutioner) finalizeExecute(ctx context.Context, dep *queued
// error handling, etc.
var uninstallOpts UninstallOptions
if opts, ok := e.parentAction.(UninstallOptions); ok {
//If we have depsv2 on, and no parentinstallation label, do not uninstall
// this must be uninstalled directly
if _, ok := e.depArgs.Installation.Labels["sh.porter.parentInstallation"]; !ok && dep.SharingMode {
return nil
}
uninstallOpts = opts
}

//
if e.parentAction.GetAction() == "upgrade" {
if _, ok := e.depArgs.Installation.Labels["sh.porter.parentInstallation"]; !ok && dep.SharingMode {
return nil
}
}

var executeErrs error
span.Infof("Executing dependency %s...", dep.Alias)
err := e.CNAB.Execute(ctx, e.depArgs)
Expand Down
20 changes: 0 additions & 20 deletions tests/integration/dependenciesv1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,23 +244,3 @@ func uninstallWordpressBundle(ctx context.Context, p *porter.TestPorter, namespa
assert.Equal(p.T(), "ci", i.CredentialSets[0], "expected to use the alternate credential set")

}

func installMySQLbundle(ctx context.Context, p *porter.TestPorter, namespace string) {
p.CopyDirectory(filepath.Join(p.RepoRoot, "build/testdata/bundles/mysql"), ".", false)
installOpts := porter.NewInstallOptions()
installOpts.Namespace = namespace
installOpts.CredentialIdentifiers = []string{"ci"} // Use the ci credential set, porter should remember this for later

err := installOpts.Validate(ctx, []string{}, p.Porter)
require.NoError(p.T(), err, "validation of install opts for shared mysql bundle failed")

err = p.InstallBundle(ctx, installOpts)
require.NoError(p.T(), err, "install of shared mysql bundle failed namespace %s", namespace)

mysqlinst, err := p.Installations.GetInstallation(ctx, namespace, "mysql")
require.NoError(p.T(), err, "could not fetch installation status for the dependency")

//Set the label on the installaiton so Porter knows to grab it
mysqlinst.SetLabel("sh.porter.SharingGroup", "myapp")

}
18 changes: 8 additions & 10 deletions tests/integration/dependenciesv2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ func TestSharedDependencies(t *testing.T) {
t.Parallel()

p := porter.NewTestPorter(t)
p.Config.SetExperimentalFlags(experimental.FlagDependenciesV2)
ctx := p.SetupIntegrationTest()
bunDir := setupFS(ctx, p)
defer os.RemoveAll(bunDir)
p.Config.SetExperimentalFlags(experimental.FlagDependenciesV2)

namespace := p.RandomString(10)
setupMysql(ctx, p, namespace, bunDir)
Expand Down Expand Up @@ -73,6 +73,8 @@ func setupMysql(ctx context.Context, p *porter.TestPorter, namespace string, bun

//Set the label on the installaiton so Porter knows to grab it
mysqlinst.SetLabel("sh.porter.SharingGroup", "myapp")
err = p.Installations.UpdateInstallation(ctx, mysqlinst)
require.NoError(p.T(), err, "could not add label to mysql inst")

}

Expand Down Expand Up @@ -118,10 +120,6 @@ func setupWordpress_v2(ctx context.Context, p *porter.TestPorter, namespace stri
i, err = p.Installations.GetInstallation(ctx, namespace, "wordpress")
require.NoError(p.T(), err, "could not fetch claim for the root bundle")
assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the root bundle wasn't recorded as being installed successfully")

//todo(schristoff): We need to ensure that parameters/outputs
// from the existing dependency
// get bubbled up to the new parent
}

func cleanupWordpressBundle_v2(ctx context.Context, p *porter.TestPorter, namespace string) {
Expand Down Expand Up @@ -160,18 +158,17 @@ func upgradeWordpressBundle_v2(ctx context.Context, p *porter.TestPorter, namesp
err = p.UpgradeBundle(ctx, upgradeOpts)
require.NoError(p.T(), err, "upgrade of root bundle failed")

// Verify that the dependency claim is upgraded
// Verify that the dependency claim is still installed
// upgrade should not change our status
i, err := p.Installations.GetInstallation(ctx, namespace, "mysql")
require.NoError(p.T(), err, "could not fetch claim for the dependency")
c, err := p.Installations.GetLastRun(ctx, i.Namespace, i.Name)
require.NoError(p.T(), err, "GetLastClaim failed")
assert.Equal(p.T(), cnab.ActionUpgrade, c.Action, "the dependency wasn't recorded as being upgraded")

assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the dependency wasn't recorded as being upgraded successfully")

// Verify that the bundle claim is upgraded
i, err = p.Installations.GetInstallation(ctx, namespace, "wordpress")
require.NoError(p.T(), err, "could not fetch claim for the root bundle")
c, err = p.Installations.GetLastRun(ctx, i.Namespace, i.Name)
c, err := p.Installations.GetLastRun(ctx, i.Namespace, i.Name)
require.NoError(p.T(), err, "GetLastClaim failed")
assert.Equal(p.T(), cnab.ActionUpgrade, c.Action, "the root bundle wasn't recorded as being upgraded")
assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the root bundle wasn't recorded as being upgraded successfully")
Expand Down Expand Up @@ -220,6 +217,7 @@ func invokeWordpressBundle_v2(ctx context.Context, p *porter.TestPorter, namespa
}

func uninstallWordpressBundle_v2(ctx context.Context, p *porter.TestPorter, namespace string) {

uninstallOptions := porter.NewUninstallOptions()
uninstallOptions.Namespace = namespace
// Now go back to using the original set of credentials
Expand Down

0 comments on commit 049e220

Please sign in to comment.