Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support tweaking the operation before running it #112

Merged
merged 3 commits into from
Sep 10, 2019

Conversation

carolynvs
Copy link
Contributor

This will allow a tool to apply additional configuration, such as injecting additional files or environment variables, before the operation is run.

In our case, it will allow Porter to continue to implement dependencies without having to make extensive changes to cnab-go because it can inject the changes it requires through this configuration function instead of modifying the cnab-go code directly.

action/install.go Outdated Show resolved Hide resolved
action/install.go Outdated Show resolved Hide resolved
Copy link
Contributor

@glyn glyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I proposed a couple of small refactorings, but I'm also interested to know whether duffle could use this mechanism to mount relocation mapping files instead of using its current approach of wrapping the driver. A draft duffle PR utilising this PR would be great (and I'm happy to help code it once this PR is ready to merge).

@@ -25,6 +29,10 @@ func (i *Install) Run(c *claim.Claim, creds credentials.Set, w io.Writer) error
return err
}

if i.OperationConfig != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about adding a variadic parameter to the Run function signature instead of storing it into the structs?
func (i *Install) Run(c *claim.Claim, creds credentials.Set, w io.Writer, ops OperationConfig...) error
Something like this? I guess it is a more functional way to apply custom configs?
WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally made the change that way. 😀 It would be a breaking change since it alters the method signature. I wasn't sure if that would be a welcome change(?) so I went with this instead for an initial proposal.

It looked like this:

func (i *Install) Run(c *claim.Claim, creds credentials.Set, ops OperationConfig...)

Setting the writer on the op was something that the caller managed via the ops parameter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I was wondering about that too, but as we didn't hit the 1.0 yet, should we "care" about about breaking changes? I think we should focus on the API design instead 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's what it would look like with @silvin-lubecki 's suggested change.

type OperationConfigFunc func(op *driver.Operation) error

type OperationConfigs []OperationConfigFunc

// ApplyConfig safely applies the configuration function to the operation, if defined,
// and returns any error.
func (cfgs OperationConfigs) ApplyConfig(op *driver.Operation) error {
	var err error
	for _, cfg := range cfgs {
		err = cfg(op)
		if err != nil {
			return err
		}
	}
	return nil
}

// Run performs an installation and updates the Claim accordingly
func (i *Install) Run(c *claim.Claim, creds credentials.Set, w io.Writer, opCfgs ...OperationConfigFunc) error {
	// ...

	err = OperationConfigs(opCfgs).ApplyConfig(op)
	if err != nil {
		return err
	}

I'm leaving the writer alone for now just to show what the overall change looks like. It could made into a config func that everyone would have to pass in (more disruptive), or we could keep it as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@glyn What do you think?

@carolynvs
Copy link
Contributor Author

I just dug up what duffle is doing (below) immediately before run and I think this would work for duffle as well.

https://github.com/deislabs/duffle/blob/0c0cf660e05c549599056206214d9ead72b13bd7/cmd/duffle/main.go#L146-L156

Seems to me that duffle could add an config action with this function's logic and not need the wrapper.

@carolynvs
Copy link
Contributor Author

@glyn Ok, just pushed up another commit with your suggested changes.

carolynvs pushed a commit to carolynvs/porter that referenced this pull request Aug 20, 2019
carolynvs pushed a commit to carolynvs/porter that referenced this pull request Aug 20, 2019
carolynvs pushed a commit to carolynvs/porter that referenced this pull request Aug 20, 2019
type ConfigurableAction struct {
// OperationConfig is an optional handler that applies additional
// configuration to an operation before it is executed.
OperationConfig OperationConfigFunc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have prefer a slice here, so user can have multiple unitary config modifiers. I guess it would help factorizing between different actions. WDYT?

},
Error: nil,
}
inst := &RunCustom{Driver: d, Action: "test"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should factorize those tests, as they are exactly the same for all the actions (good hint is that this action is still called inst 😇 ).

Copy link
Contributor

@glyn glyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for making those changes. I'm going to hold off seeing how this can help in duffle given that @silvin-lubecki is asking for more changes.

carolynvs pushed a commit to carolynvs/porter that referenced this pull request Aug 21, 2019
This will allow a tool to apply additional configuration, such as
injecting additional files or environment variables, before the
operation is run.

In our case, it will allow Porter to continue to implement dependencies
without having to make extensive changes to cnab-go because it can
inject the changes it requires through this configuration function
instead of modifying the cnab-go code directly.
This switches to applying multiple configs via the Run interface.
It includes applying the writer as well since it falls into the scope
of the new OperationalConfig.
@carolynvs
Copy link
Contributor Author

@silvin-lubecki @glyn I've updated the PR with Silvin's requested change. If you could take another look, I'm hoping to get some form of this PR (either this or the former) merged before the cutoff. Thanks!

@@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"gopkg.in/yaml.v2"
yaml "gopkg.in/yaml.v2"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think this alias is no-op, go already uses the part before the first dot as import name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm aware it's a noop. It's an artifact of using GoLand for an IDE and for the life of me I can't figure out how to stop it from introducing those. When I remove the alias, it adds it back. 🤷‍♀ Running goimports (which I do on file save) doesn't clean those up either.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just asked the twitterverse for help. https://twitter.com/carolynvs/status/1169993866503757827

Copy link
Contributor

@silvin-lubecki silvin-lubecki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @carolynvs 🤗 I only have few nit/comments, but non blocking, could be made in a follow-up 👍

@carolynvs carolynvs merged commit 93515c7 into cnabio:master Sep 10, 2019
@carolynvs carolynvs deleted the op-config-func branch September 10, 2019 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants