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

Add new build driver for buildkit #1567

Merged
merged 9 commits into from
May 17, 2021
Merged

Conversation

carolynvs
Copy link
Member

@carolynvs carolynvs commented May 8, 2021

What does this change

  • Add --experimental flag to root porter command
  • Add experimental flags to config file. These features are disabled by default.
  • Add experimental flag for "build-drivers". This allows specifying the build driver, e.g. docker, buildkit, in the config file.
  • Add driver for buildkit.
  • Document drivers and how to configure them.
  • Document experimental flags
  • porter create generates a Dockerfile that uses buildkit when that feature is enabled

❓ As a follow-on should a bundle be able to say "I use buildkit!" and then fail if it's not enabled, or automatically pick that driver

example configuration to enable the feature:

~/.porter/config.toml

experimental = ["build-drivers"]
build-driver = "buildkit"

You can also set it with environment variables

export PORTER_EXPERIMENTAL=build-drivers (comma seperated)
export PORTER_BUILD_DRIVER=buildkit

or with flags

porter build --experimental build-drivers --driver buildkit

What issue does it fix

Closes #1268

Notes for the reviewer

As I was working on this I realized that we have some problems around when the configuration is loaded, and accessing it without accidentally getting a nil pointer exception. So I did a bit of refactoring to address since it was blocking the --experimental flag. It was prohibitive to refactor in a separate PR so hopefully having this smooshed together is reviewable.

  • Refactor porter's config and data structures so that we can't get nil pointer exceptions or try to access the configuration data before it is loaded.
  • Move helper functions to Config so that they are easier to find.
  • Remove helper functions for config values that aren't needed anymore because its safe to directly access the bound field going forward.
  • Use a fork of viper with a patch for a bug in how we load configuration when a config file is not found. We should still bind to environment variables.

Checklist

  • Unit Tests
  • Documentation
  • Schema (porter.yaml)

@carolynvs carolynvs changed the base branch from main to v1 May 11, 2021 19:08
@carolynvs carolynvs force-pushed the buildkit branch 3 times, most recently from 724f1b9 to 446bde2 Compare May 13, 2021 12:50
@carolynvs
Copy link
Member Author

/azp run porter-integration

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

carolynvs added 4 commits May 13, 2021 13:34
Signed-off-by: Carolyn Van Slyck <[email protected]>
* Add experimental flags to config file. These features are disabled
by default.
* Add experimental flag for "build-drivers". This allows specifying the
build driver, e.g. docker, buildkit, in the config file.
* Add driver for buildkit.

Signed-off-by: Carolyn Van Slyck <[email protected]>
* Add --experimental flag that accepts a comma separated list of feature
flags. Right now we only support "build-drivers".
* Refactor porter's config and data structures so that we can't get nil
pointer exceptions or try to access the configuration data before it is
loaded.
* Move helper functions to Config so that they are easier to find.
* Remove helper functions for config values that aren't needed anymore
because its safe to directly access the bound field going forward.
* Use a fork of viper with a patch for a bug in how we load
configuration when a config file is not found. We should still bind to
environment variables.

Signed-off-by: Carolyn Van Slyck <[email protected]>
Signed-off-by: Carolyn Van Slyck <[email protected]>
carolynvs added 2 commits May 13, 2021 13:39
Signed-off-by: Carolyn Van Slyck <[email protected]>
Signed-off-by: Carolyn Van Slyck <[email protected]>
@carolynvs
Copy link
Member Author

/azp run porter-integration

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@carolynvs carolynvs marked this pull request as ready for review May 13, 2021 19:49
docs/content/custom-dockerfile.md Show resolved Hide resolved
pkg/claims/claimStorage_test.go Show resolved Hide resolved
pkg/config/config_test.go Outdated Show resolved Hide resolved
pkg/config/config_test.go Outdated Show resolved Hide resolved
pkg/config/datastore.go Outdated Show resolved Hide resolved
pkg/context/helpers.go Show resolved Hide resolved
)

// ParseFlags converts a list of feature flag names into a bit map for faster lookups.
func ParseFlags(flags []string) FeatureFlags {
Copy link
Member

Choose a reason for hiding this comment

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

Neat, I'll have to keep this technique in mind.

Copy link
Member Author

Choose a reason for hiding this comment

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

I could have converted to a map and then used key lookups, but what is nice about this is that it's faster than a map lookup and uses less space too.

return o.bundleFileOptions.Validate(p.Context)
}

func stringSliceContains(allowedValues []string, value string) bool {
Copy link
Member

Choose a reason for hiding this comment

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

Should we move this to a more generic helpers file/location, or nah?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we could use this in a couple places. I just was dithering about naming a package util, and imagined what people would think. 😂

Screen Shot 2021-05-14 at 8 05 57 AM

cmd/porter/bundle.go Show resolved Hide resolved
Copy link
Member

@vdice vdice left a comment

Choose a reason for hiding this comment

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

Awesome work! Only had minor suggestions.

One other minor issue I was curious about. When I supply an invalid/unsupported build driver, the error isn't as expected:

 $ p build --experimental build-drivers --driver buildx
Copying porter runtime ===>
Copying mixins ===>
Copying mixin exec ===>

Generating Dockerfile =======>
Error: unable to generate Dockerfile: error generating the Dockerfile: error loading default Dockerfile template: open templates/build/buildx.Dockerfile: file does not exist

In other words, I'm wondering if the cli can instead bubble up the specific error that the spec'd build driver isn't supported?

@carolynvs
Copy link
Member Author

I have created #1582 to get feedback on auto-build for publish.

I did have code that tried to validate the driver, looks like bad values can still slip through. I'll fix that.

* Fix setting defaults on viper config
* Add missing example to custom dockerfile page
* Fix comments
* Bind --driver to the command flag, not the config struct directly
* Add check to AddTestDirectoryFromRoot

Signed-off-by: Carolyn Van Slyck <[email protected]>
Copy link
Member

@vdice vdice left a comment

Choose a reason for hiding this comment

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

One last thing to check. When I supply a bogus driver in Porter's config, I'm not seeing the cli error out on porter build (no flags or env vars set). Do you see the same? I'm using:

experimental = ["build-drivers"]
build-driver = "foo"

carolynvs added 2 commits May 14, 2021 17:43
I've added a regression test to ensure that when we set a flag for
something that falls back to the config, but it also has a flag default
set, that the config value is properly bound to the flag.

Fixes the edge case of bad config data and the user running porter build
without specifying the --driver flag. Previously it was defaulting to
the flag's default instead of binding to the config value.

I've also tweaked the TestPorter so that it doesn't accidentally load
the config and env vars from your dev machine when running tests.

Signed-off-by: Carolyn Van Slyck <[email protected]>
Make it easier for tests or downstream consumers of our library to
enable experimental flags quickly without having to understand our
configuration system.

Signed-off-by: Carolyn Van Slyck <[email protected]>
Copy link
Member

@vdice vdice left a comment

Choose a reason for hiding this comment

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

LGTM!

@carolynvs
Copy link
Member Author

Sorry this got a bit weird. I realized that there were some gaps in our configuration scheme exposed by what I wanted to do in this PR. Hopefully we've got enough tests now to cover all the weird cases.

@carolynvs
Copy link
Member Author

/azp run porter-integration

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@carolynvs carolynvs merged commit 3fc2a0e into getporter:v1 May 17, 2021
@carolynvs carolynvs deleted the buildkit branch May 17, 2021 14:28
ThorstenHans pushed a commit to ThorstenHans/porter that referenced this pull request May 18, 2021
* rename build provider
* Add new build driver for buildkit
    * Add experimental flags to config file. These features are disabled
by default.
    * Add experimental flag for "build-drivers". This allows specifying the
build driver, e.g. docker, buildkit, in the config file.
    * Add driver for buildkit.
* Add --experimental flag and refactor config/data
    * Add --experimental flag that accepts a comma separated list of feature
flags. Right now we only support "build-drivers".
    * Refactor porter's config and data structures so that we can't get nil
pointer exceptions or try to access the configuration data before it is
loaded.
    * Move helper functions to Config so that they are easier to find.
    * Remove helper functions for config values that aren't needed anymore
because its safe to directly access the bound field going forward.
    * Use a fork of viper with a patch for a bug in how we load
configuration when a config file is not found. We should still bind to
environment variables.

* Fix review feedback
    * Fix setting defaults on viper config
    * Add missing example to custom dockerfile page
    * Fix comments
    * Bind --driver to the command flag, not the config struct directly
    * Add check to AddTestDirectoryFromRoot

* Load defaults before applying config to flags

I've added a regression test to ensure that when we set a flag for
something that falls back to the config, but it also has a flag default
set, that the config value is properly bound to the flag.

Fixes the edge case of bad config data and the user running porter build
without specifying the --driver flag. Previously it was defaulting to
the flag's default instead of binding to the config value.

I've also tweaked the TestPorter so that it doesn't accidentally load
the config and env vars from your dev machine when running tests.

* Support setting experimental flags programmatically

Make it easier for tests or downstream consumers of our library to
enable experimental flags quickly without having to understand our
configuration system.

Signed-off-by: Carolyn Van Slyck <[email protected]>
This was referenced May 22, 2021
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.

Toggle buildkit features in porter.yaml
2 participants