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

Extension package #1661

Merged
merged 22 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5a4ceea
add package-extension
itsdarshankumar Mar 5, 2023
1be495d
fix format
itsdarshankumar Mar 5, 2023
1891ec1
fix read for extensions
itsdarshankumar Mar 5, 2023
f943150
fix extension builder
itsdarshankumar Mar 6, 2023
ec105ea
fix builder
itsdarshankumar Mar 6, 2023
0baa22d
fix extension builder for saveasfile
itsdarshankumar Mar 6, 2023
f9881b9
Merge branch 'main' into extension-package
itsdarshankumar Mar 6, 2023
cc63b9e
patch builder for extensions
itsdarshankumar Mar 7, 2023
dd4f694
patch builder and builder test to adapt extensions
itsdarshankumar Mar 7, 2023
20fceed
add tests for extension_package command
itsdarshankumar Mar 7, 2023
bebfe40
add tests for package_extension
itsdarshankumar Mar 13, 2023
9525a10
fix tests
itsdarshankumar Mar 13, 2023
26b6e89
Merge branch 'main' into extension-package
itsdarshankumar Mar 13, 2023
edd1c61
fix folder cleaning error validation in test
itsdarshankumar Mar 16, 2023
4efe830
add extension metadata tests in builder
itsdarshankumar Mar 17, 2023
747d127
add config tests
itsdarshankumar Mar 17, 2023
ab3f5f0
extend success messages for extensions and buildpack package
itsdarshankumar Mar 24, 2023
91d00e6
Merge branch 'main' into extension-package
itsdarshankumar Mar 24, 2023
35e706e
Merge branch 'main' into extension-package
itsdarshankumar Mar 29, 2023
faba2cb
Merge branch 'main' into extension-package
jkutner Mar 30, 2023
3004465
update error in pull buildpack test
itsdarshankumar Mar 30, 2023
3e75a40
add nil condition for err
itsdarshankumar Mar 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions buildpackage/config_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const defaultOS = "linux"
// Config encapsulates the possible configuration options for buildpackage creation.
type Config struct {
Buildpack dist.BuildpackURI `toml:"buildpack"`
Extension dist.BuildpackURI `toml:"extension"`
Dependencies []dist.ImageOrURI `toml:"dependencies"`
Platform dist.Platform `toml:"platform"`
}
Expand All @@ -32,6 +33,17 @@ func DefaultConfig() Config {
}
}

func DefaultExtensionConfig() Config {
return Config{
Extension: dist.BuildpackURI{
URI: ".",
},
Platform: dist.Platform{
OS: defaultOS,
},
}
}

// NewConfigReader returns an instance of ConfigReader. It does not take any parameters.
func NewConfigReader() *ConfigReader {
return &ConfigReader{}
Expand Down Expand Up @@ -61,8 +73,11 @@ func (r *ConfigReader) Read(path string) (Config, error) {
)
}

if packageConfig.Buildpack.URI == "" {
return packageConfig, errors.Errorf("missing %s configuration", style.Symbol("buildpack.uri"))
if packageConfig.Buildpack.URI == "" && packageConfig.Extension.URI == "" {
if packageConfig.Buildpack.URI == "" {
return packageConfig, errors.Errorf("missing %s configuration", style.Symbol("buildpack.uri"))
}
return packageConfig, errors.Errorf("missing %s configuration", style.Symbol("extension.uri"))
}

if packageConfig.Platform.OS == "" {
Expand Down
29 changes: 29 additions & 0 deletions buildpackage/config_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/sclevine/spec/report"

"github.com/buildpacks/pack/buildpackage"
"github.com/buildpacks/pack/pkg/dist"
h "github.com/buildpacks/pack/testhelpers"
)

Expand All @@ -33,6 +34,34 @@ func testBuildpackageConfigReader(t *testing.T, when spec.G, it spec.S) {
os.RemoveAll(tmpDir)
})

it("returns default buildpack config", func() {
expected := buildpackage.Config{
Buildpack: dist.BuildpackURI{
URI: ".",
},
Platform: dist.Platform{
OS: "linux",
},
}
actual := buildpackage.DefaultConfig()

h.AssertEq(t, actual, expected)
})

it("returns default extension config", func() {
expected := buildpackage.Config{
Extension: dist.BuildpackURI{
URI: ".",
},
Platform: dist.Platform{
OS: "linux",
},
}
actual := buildpackage.DefaultExtensionConfig()

h.AssertEq(t, actual, expected)
})

it("returns correct config when provided toml file is valid", func() {
configFile := filepath.Join(tmpDir, "package.toml")

Expand Down
6 changes: 5 additions & 1 deletion internal/commands/buildpack_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,12 @@ func BuildpackPackage(logger logging.Logger, cfg config.Config, packager Buildpa
if flags.Publish {
action = "published"
}
location := "docker daemon"
if flags.Format == client.FormatFile {
location = "file"
}

logger.Infof("Successfully %s package %s", action, style.Symbol(name))
logger.Infof("Successfully %s package %s and saved to %s", action, style.Symbol(name), location)
return nil
}),
}
Expand Down
1 change: 1 addition & 0 deletions internal/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type PackClient interface {
CreateBuilder(context.Context, client.CreateBuilderOptions) error
NewBuildpack(context.Context, client.NewBuildpackOptions) error
PackageBuildpack(ctx context.Context, opts client.PackageBuildpackOptions) error
PackageExtension(ctx context.Context, opts client.PackageBuildpackOptions) error
Build(context.Context, client.BuildOptions) error
RegisterBuildpack(context.Context, client.RegisterBuildpackOptions) error
YankBuildpack(client.YankBuildpackOptions) error
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func NewExtensionCommand(logger logging.Logger, cfg config.Config, client PackCl

cmd.AddCommand(ExtensionInspect(logger, cfg, client))
// client and packageConfigReader to be passed later on
cmd.AddCommand(ExtensionPackage(logger, cfg))
cmd.AddCommand(ExtensionPackage(logger, cfg, client, packageConfigReader))
// client to be passed later on
cmd.AddCommand(ExtensionNew(logger))
cmd.AddCommand(ExtensionPull(logger, cfg, client))
Expand Down
97 changes: 87 additions & 10 deletions internal/commands/extension_package.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,115 @@
package commands

import (
"context"
"path/filepath"

"github.com/pkg/errors"
"github.com/spf13/cobra"

pubbldpkg "github.com/buildpacks/pack/buildpackage"
"github.com/buildpacks/pack/internal/config"
"github.com/buildpacks/pack/internal/style"
"github.com/buildpacks/pack/pkg/client"
"github.com/buildpacks/pack/pkg/image"
"github.com/buildpacks/pack/pkg/logging"
)

// ExtensionPackageFlags define flags provided to the ExtensionPackage command
type ExtensionPackageFlags struct {
PackageTomlPath string
Format string
Publish bool
Policy string
ExtensionRegistry string
Path string
PackageTomlPath string
Format string
Publish bool
Policy string
}

// Packager and PackageConfigReader to be added here and argument also to be added in the function
// ExtensionPackager packages extensions
type ExtensionPackager interface {
PackageExtension(ctx context.Context, options client.PackageBuildpackOptions) error
}

// ExtensionPackage packages (a) extension(s) into OCI format, based on a package config
func ExtensionPackage(logger logging.Logger, cfg config.Config) *cobra.Command {
func ExtensionPackage(logger logging.Logger, cfg config.Config, packager ExtensionPackager, packageConfigReader PackageConfigReader) *cobra.Command {
var flags ExtensionPackageFlags
cmd := &cobra.Command{
Use: "package <name> --config <config-path>",
Short: "Package an extension in OCI format",
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: logError(logger, func(cmd *cobra.Command, args []string) error {
// logic will be added here
if err := validateExtensionPackageFlags(&flags); err != nil {
return err
}

stringPolicy := flags.Policy
if stringPolicy == "" {
stringPolicy = cfg.PullPolicy
}

pullPolicy, err := image.ParsePullPolicy(stringPolicy)
if err != nil {
return errors.Wrap(err, "parsing pull policy")
}

exPackageCfg := pubbldpkg.DefaultExtensionConfig()
relativeBaseDir := ""
if flags.PackageTomlPath != "" {
exPackageCfg, err = packageConfigReader.Read(flags.PackageTomlPath)
if err != nil {
return errors.Wrap(err, "reading config")
}

relativeBaseDir, err = filepath.Abs(filepath.Dir(flags.PackageTomlPath))
if err != nil {
return errors.Wrap(err, "getting absolute path for config")
}
}
name := args[0]
if flags.Format == client.FormatFile {
switch ext := filepath.Ext(name); ext {
case client.CNBExtension:
case "":
name += client.CNBExtension
default:
logger.Warnf("%s is not a valid extension for a packaged extension. Packaged extensions must have a %s extension", style.Symbol(ext), style.Symbol(client.CNBExtension))
}
}

if err := packager.PackageExtension(cmd.Context(), client.PackageBuildpackOptions{
RelativeBaseDir: relativeBaseDir,
Name: name,
Format: flags.Format,
Config: exPackageCfg,
Publish: flags.Publish,
PullPolicy: pullPolicy,
}); err != nil {
return err
}
action := "created"
if flags.Publish {
action = "published"
}
location := "docker daemon"
if flags.Format == client.FormatFile {
location = "file"
}

logger.Infof("Successfully %s package %s and saved to %s", action, style.Symbol(name), location)
return nil
}),
}

// flags will be added here

cmd.Flags().StringVarP(&flags.PackageTomlPath, "config", "c", "", "Path to package TOML config")
cmd.Flags().StringVarP(&flags.Format, "format", "f", "", `Format to save package as ("image" or "file")`)
cmd.Flags().BoolVar(&flags.Publish, "publish", false, `Publish to registry (applies to "--format=image" only)`)
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
AddHelpFlag(cmd, "package")
return cmd
}

func validateExtensionPackageFlags(p *ExtensionPackageFlags) error {
if p.Publish && p.Policy == image.PullNever.String() {
return errors.Errorf("--publish and --pull-policy=never cannot be used together. The --publish flag requires the use of remote images.")
}
return nil
}
Loading